feat: Pictured
This commit is contained in:
parent
c92ca306b4
commit
103b6d4899
106
packages/entity/traits/pictured.js
Normal file
106
packages/entity/traits/pictured.js
Normal 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) {}
|
Loading…
Reference in New Issue
Block a user