2019-04-05 07:17:01 -05:00
|
|
|
import {compose} from '@avocado/core';
|
2019-04-05 11:54:38 -05:00
|
|
|
import {Rectangle, Vector} from '@avocado/math';
|
2019-04-05 07:17:01 -05:00
|
|
|
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)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-04-05 11:54:38 -05:00
|
|
|
get rectangle() {
|
|
|
|
return Rectangle.compose(
|
|
|
|
Vector.sub(this.position, Vector.scale(this.viewSize, 0.5)),
|
|
|
|
this.viewSize,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-04-05 07:17:01 -05:00
|
|
|
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
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|