2019-03-18 20:07:05 -05:00
|
|
|
import {compose} from '@avocado/core';
|
2019-03-19 10:40:59 -05:00
|
|
|
import {hasGraphics, Container} from '@avocado/graphics';
|
2019-04-10 21:02:15 -05:00
|
|
|
import {Rectangle, Vector} from '@avocado/math';
|
2019-03-18 20:07:05 -05:00
|
|
|
|
2019-03-23 23:24:18 -05:00
|
|
|
import {StateProperty, Trait} from '../trait';
|
2019-03-18 20:07:05 -05:00
|
|
|
|
|
|
|
const decorate = compose(
|
|
|
|
);
|
|
|
|
|
|
|
|
class GraphicalBase extends Trait {
|
|
|
|
|
|
|
|
static defaultParams() {
|
|
|
|
return {
|
|
|
|
trackPosition: true,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-03-19 11:25:42 -05:00
|
|
|
initialize() {
|
2019-03-19 10:40:59 -05:00
|
|
|
if (hasGraphics) {
|
|
|
|
this._container = new Container();
|
|
|
|
}
|
2019-03-19 11:03:48 -05:00
|
|
|
this.trackPosition = this.params.get('trackPosition');
|
2019-03-18 20:07:05 -05:00
|
|
|
}
|
|
|
|
|
2019-03-20 23:23:34 -05:00
|
|
|
destroy() {
|
|
|
|
if (this._container) {
|
|
|
|
this._container.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-18 20:07:05 -05:00
|
|
|
get container() {
|
|
|
|
return this._container;
|
|
|
|
}
|
|
|
|
|
2019-03-26 17:17:09 -05:00
|
|
|
get graphicalBoundingBox() {
|
|
|
|
// Collect all bounding boxes.
|
|
|
|
const graphicalBoundingBoxes = this.entity.invokeHookFlat(
|
|
|
|
'graphicalBoundingBoxes'
|
|
|
|
);
|
|
|
|
if (0 === graphicalBoundingBoxes.length) {
|
|
|
|
return [0, 0, 0, 0];
|
|
|
|
}
|
|
|
|
let unifiedBoundingBox = [0, 0, 0, 0];
|
|
|
|
for (const graphicalBoundingBox of graphicalBoundingBoxes) {
|
|
|
|
unifiedBoundingBox = Rectangle.united(
|
|
|
|
unifiedBoundingBox,
|
|
|
|
graphicalBoundingBox,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return unifiedBoundingBox;
|
|
|
|
}
|
|
|
|
|
2019-03-19 11:03:48 -05:00
|
|
|
shouldSynchronizePosition() {
|
2019-03-19 11:59:47 -05:00
|
|
|
return this.entity.container && this.trackPosition;
|
2019-03-19 11:03:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
synchronizePosition() {
|
2019-03-19 11:48:46 -05:00
|
|
|
if (!('position' in this.entity)) {
|
|
|
|
return;
|
2019-03-19 11:25:42 -05:00
|
|
|
}
|
2019-04-10 21:02:15 -05:00
|
|
|
this.entity.container.position = Vector.round(this.entity.position);
|
2019-03-19 21:27:41 -05:00
|
|
|
this.entity.container.zIndex = this.entity.y;
|
2019-03-19 11:03:48 -05:00
|
|
|
}
|
|
|
|
|
2019-03-18 20:07:05 -05:00
|
|
|
listeners() {
|
2019-03-19 10:21:00 -05:00
|
|
|
const listeners = {};
|
2019-03-19 11:03:48 -05:00
|
|
|
if (this.shouldSynchronizePosition()) {
|
2019-03-21 00:15:15 -05:00
|
|
|
listeners.traitAdded = (type) => {
|
|
|
|
if (-1 === [
|
|
|
|
'graphical',
|
|
|
|
'positioned',
|
|
|
|
].indexOf(type)) {
|
2019-03-19 11:03:48 -05:00
|
|
|
return;
|
2019-03-18 20:07:05 -05:00
|
|
|
}
|
2019-03-19 11:03:48 -05:00
|
|
|
this.synchronizePosition();
|
2019-03-19 10:21:00 -05:00
|
|
|
};
|
2019-04-11 07:38:28 -05:00
|
|
|
listeners.tick = () => {
|
2019-03-19 11:03:48 -05:00
|
|
|
this.synchronizePosition();
|
2019-03-19 10:21:00 -05:00
|
|
|
};
|
2019-03-18 20:07:05 -05:00
|
|
|
}
|
2019-03-19 10:21:00 -05:00
|
|
|
return listeners;
|
2019-03-18 20:07:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Graphical extends decorate(GraphicalBase) {}
|