import {compose} from '@avocado/core'; import {Rectangle, Vector} from '@avocado/math'; import {EventEmitter, Property} from '@avocado/mixins'; 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() { super(); this.imageUri = undefined; } 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(parseInt(direction)); } 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; } }