feat: Pictured

This commit is contained in:
cha0s 2019-03-20 20:15:04 -05:00
parent c92ca306b4
commit 103b6d4899

View File

@ -0,0 +1,106 @@
import {compose} from '@avocado/core';
import {Image, Sprite} from '@avocado/graphics';
import {Vector} from '@avocado/math';
import {simpleState, Trait} from '../trait';
const decorate = compose(
simpleState('currentImage', {
track: true,
}),
);
class PicturedBase extends Trait {
static defaultParams() {
return {
images: {},
};
}
static defaultState() {
return {
currentImage: 'initial',
};
}
hideImage(key) {
if (!this.sprites) {
return;
}
const sprite = this.sprites[key];
if (!sprite) {
return;
}
this.entity.container.removeChild(sprite);
}
initialize() {
this.sprites = undefined;
}
loadImagesIfPossible() {
if (!this.entity.container) {
return;
}
if (this.sprites) {
return;
}
const images = this.params.get('images');
// Load all images.
this.sprites = {};
for (const key in images) {
const {uri} = images[key];
Image.load(uri).then((image) => {
this.sprites[key] = new Sprite(image);
const isCurrentImage = key === this.entity.currentImage;
if (isCurrentImage) {
this.showImage(key);
}
});
}
}
showImage(key) {
if (!this.sprites) {
return;
}
const sprite = this.sprites[key];
if (!sprite) {
return;
}
const images = this.params.get('images');
const {offset} = images[key];
const {image} = sprite;
const size = image.size;
const halfway = Vector.scale(size, -0.5);
sprite.position = Vector.add(halfway, offset);
this.entity.container.addChild(sprite);
}
listeners() {
return {
currentImageChanged: (oldKey) => {
// Only client/graphics.
if (!this.sprites) {
return;
}
// Swap the image.
this.hideImage(oldKey);
this.showImage(this.entity.currentImage);
},
traitAdded: (trait) => {
if (-1 === [
'graphical',
'pictured',
].indexOf(trait.constructor.type())) {
return;
}
this.loadImagesIfPossible();
},
};
}
}
export class Pictured extends decorate(PicturedBase) {}