avocado-old/packages/topdown/camera.js
2019-04-05 08:17:01 -04:00

83 lines
1.9 KiB
JavaScript

import {compose} from '@avocado/core';
import {Vector} from '@avocado/math';
import {EventEmitter, Property} from '@avocado/mixins';
const decorate = compose(
EventEmitter,
Vector.Mixin('areaSize', 'areaWidth', 'areaHeight', {
default: [0, 0],
track: true,
}),
Property('drag', {
default: 1000,
}),
Vector.Mixin('position', 'x', 'y', {
default: [0, 0],
track: true,
}),
Vector.Mixin('realPosition', 'realX', 'realY', {
default: [0, 0],
track: true,
}),
Vector.Mixin('viewSize', 'viewWidth', 'viewHeight', {
default: [0, 0],
track: true,
}),
);
export class Camera extends decorate(class {}) {
constructor() {
super();
this.onAreaSizeChanged = this.onAreaSizeChanged.bind(this);
this.on('areaSizeChanged', this.onAreaSizeChanged);
this.onViewSizeChanged = this.onViewSizeChanged.bind(this);
this.on('viewSizeChanged', this.onViewSizeChanged);
}
destroy() {
this.off('areaSizeChanged', this.onAreaSizeChanged);
this.off('viewSizeChanged', this.onViewSizeChanged);
}
onAreaSizeChanged() {
this.position = this.position;
}
onViewSizeChanged() {
this.position = this.position;
}
get position() {
return super.position;
}
set position(position) {
if (0 === Vector.area(this.areaSize)) {
return super.position = position;
}
if (0 === Vector.area(this.viewSize)) {
return super.position = position;
}
const halfViewSize = Vector.scale(this.viewSize, 0.5);
super.position = Vector.clamp(
position,
halfViewSize,
Vector.sub(this.areaSize, halfViewSize)
);
}
tick(elapsed) {
if (Vector.equalsClose(this.position, this.realPosition, 1)) {
this.realPosition = this.position;
return;
}
this.realPosition = Vector.interpolate(
this.position,
this.realPosition,
this.drag * elapsed
);
}
}