UNPKG

tofu.js

Version:

a helper three.js library for building UC-AR

152 lines (136 loc) 3.71 kB
import Animate from './Animate'; import Transition from './Transition'; // import Utils from '../utils/Utils'; import PathMotion from './PathMotion'; /** * AnimateRunner, composer any animation type * * @private */ class AnimateRunner extends Animate { /** * config a runner animation * @param {object} [options] runners config */ constructor(options) { super(options); this.runners = options.runners; this.cursor = 0; this.queues = []; this.alternate = false; this.length = this.runners.length; // TODO: Is it necessary to exist ? // this.propsMap = []; // this.prepare(); } // prepare() { // let i = 0; // let j = 0; // for (i = 0; i < this.runners.length; i++) { // const runner = this.runners[i]; // if (Utils.isUndefined(runner.to)) continue; // const keys = Object.keys(runner.to); // for (j = 0; j < keys.length; j++) { // const prop = keys[j]; // if (this.propsMap.indexOf(prop) === -1) this.propsMap.push(prop); // } // } // for (i = 0; i < this.runners.length; i++) { // const runner = this.runners[i]; // if (!runner.to) continue; // for (j = 0; j < this.propsMap.length; j++) { // const prop = this.propsMap[j]; // if (Utils.isUndefined(runner.to[prop])) runner.to[prop] = this.object.props(prop); // } // } // } /** * init a runner * @private */ initRunner() { const runner = this.runners[this.cursor]; runner.infinite = false; runner.resident = true; runner.object = this.object; let animate = null; if (runner.path) { animate = new PathMotion(runner); } else if (runner.to) { animate = new Transition(runner); } if (animate !== null) { animate.on('complete', this.nextRunner.bind(this)); this.queues.push(animate); } } /** * step to next `runner` * @param {Object} _ is hold for pose * @param {Number} time time snippet * @private */ nextRunner(_, time) { this.queues[this.cursor].init(); this.cursor += this.direction; this.timeSnippet = time; } /** * get next pose * @param {Number} snippetCache time snippet * @return {Object} pose */ nextPose(snippetCache) { if (!this.queues[this.cursor] && this.runners[this.cursor]) { this.initRunner(); } if (this.timeSnippet >= 0) { snippetCache += this.timeSnippet; this.timeSnippet = 0; } return this.queues[this.cursor].update(snippetCache); } /** * update state * @param {Number} snippet time snippet * @return {Object} pose */ update(snippet) { if (this.wait > 0) { this.wait -= Math.abs(snippet); return; } if (this.paused || !this.living || this.delayCut > 0) { if (this.delayCut > 0) this.delayCut -= Math.abs(snippet); return; } const cc = this.cursor; const pose = this.nextPose(this.direction * this.timeScale * snippet); this.emit('update', { index: cc, pose, }, this.progress / this.duration); if (this.spill()) { if (this.repeats > 0 || this.infinite) { if (this.repeats > 0) --this.repeats; this.delayCut = this.delay; this.direction = 1; this.cursor = 0; } else { if (!this.resident) this.living = false; this.emit('complete', pose); } } return pose; } /** * check progress is spill? * @return {Boolean} is spill */ spill() { // TODO: 这里应该保留溢出,不然会导致时间轴上的误差 const topSpill = this.cursor >= this.length; return topSpill; } } export default AnimateRunner;