avocado-old/packages/timing/animation.js
2019-09-19 03:19:24 -05:00

105 lines
2.0 KiB
JavaScript

import {compose, EventEmitter, Property} from '@avocado/core';
import {Rectangle, Vector} from '@avocado/math';
import {Resource} from '@avocado/resource';
import {TimedIndexMixin as TimedIndex} from './timed-index';
const decorate = compose(
EventEmitter,
TimedIndex('frame'),
Property('direction', {
default: 0,
track: true,
}),
Property('directionCount', {
default: 1,
}),
Vector.Mixin('frameSize', 'frameWidth', 'frameHeight', {
default: [0, 0],
}),
);
export class Animation extends decorate(Resource) {
constructor(json) {
super();
this.imageUri = undefined;
if ('undefined' !== typeof json) {
this.fromJSON(json);
}
}
get sourceRectangle() {
if (0 === this.frameCount) {
return [0, 0, 0, 0];
}
const frameSize = this.frameSize;
if (Vector.isZero(frameSize)) {
return [0, 0, 0, 0];
}
const offset = [
this.index % this.frameCount,
this.direction,
];
const rectangle = Rectangle.compose(
Vector.mul(frameSize, offset),
frameSize
);
return rectangle;
}
clampDirection(direction) {
switch (this.directionCount) {
case 1:
return 0;
case 4:
const directionMap = {
0: 0,
1: 1,
2: 2,
3: 3,
4: 1,
5: 1,
6: 3,
7: 3,
};
return directionMap[Math.min(7, Math.max(0, direction))];
case 8:
return Math.min(7, Math.max(0, direction));
}
}
get direction() {
return super.direction;
}
set direction(direction) {
super.direction = this.clampDirection(direction << 0);
}
reset() {
super.reset();
this.currentFrame = 0;
}
fromJSON(json) {
super.fromJSON(json);
if (json.frameRate) {
this.ticker.frequency = json.frameRate;
}
const keys = [
'directionCount',
'frameCount',
'frameSize',
'imageUri',
];
for (const key of keys) {
if (json[key]) {
this[key] = json[key];
}
}
return this;
}
}