UNPKG

dragonbones-runtime

Version:

the tools to build dragonbones file for diffrent framework

666 lines (627 loc) 20.7 kB
////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2014-present, Egret Technology. // All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of the Egret nor the // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ////////////////////////////////////////////////////////////////////////////////////// namespace egret { /** * @private */ export class ScrollEase { /** * @version Egret 2.4 * @platform Web,Native */ constructor() { egret.$error(1014); } /** * * @param amount * @returns * @version Egret 2.4 * @platform Web,Native */ public static get(amount):Function { if (amount < -1) { amount = -1; } if (amount > 1) { amount = 1; } return function (t) { if (amount == 0) { return t; } if (amount < 0) { return t * (t * -amount + 1 + amount); } return t * ((2 - t) * amount + (1 - amount)); } } /** * @version Egret 2.4 * @platform Web,Native */ public static quintOut = ScrollEase.getPowOut(5); /** * * @param pow * @returns * @version Egret 2.4 * @platform Web,Native */ public static getPowOut(pow):Function { return function (t) { return 1 - Math.pow(1 - t, pow); } } /** * @version Egret 2.4 * @platform Web,Native */ public static quartOut = ScrollEase.getPowOut(4); } /** * @private */ export class ScrollTween extends EventDispatcher { /** * @private */ private static _tweens:ScrollTween[] = []; /** * @private */ private static IGNORE = {}; /** * @private */ private static _plugins = {}; /** * @private */ private static _inited = false; /** * @private */ private _target:any = null; /** * @private */ private _useTicks:boolean = false; /** * @private */ private ignoreGlobalPause:boolean = false; /** * @private */ private loop:boolean = false; /** * @private */ private pluginData = null; /** * @private */ private _curQueueProps; /** * @private */ private _initQueueProps; /** * @private */ private _steps:any[] = null; /** * @private */ private _actions:any[] = null; /** * @private */ private paused:boolean = false; /** * @private */ private duration:number = 0; /** * @private */ private _prevPos:number = -1; /** * @private */ private position:number = null; /** * @private */ private _prevPosition:number = 0; /** * @private */ private _stepPosition:number = 0; /** * @private */ private passive:boolean = false; /** * Activate an object and add a ScrollTween animation to the object * @param target {any} The object to be activated * @param props {any} Parameters, support loop onChange onChangeObj * @param pluginData {any} Write realized * @param override {boolean} Whether to remove the object before adding a tween, the default value false * @version Egret 2.4 * @platform Web,Native * @language en_US */ /** * 激活一个对象,对其添加 ScrollTween 动画 * @param target {any} 要激活 ScrollTween 的对象 * @param props {any} 参数,支持loop(循环播放) onChange(变化函数) onChangeObj(变化函数作用域) * @param pluginData {any} 暂未实现 * @param override {boolean} 是否移除对象之前添加的tween,默认值false * @version Egret 2.4 * @platform Web,Native * @language zh_CN */ public static get(target:any, props:any = null, pluginData:any = null, override:boolean = false):ScrollTween { if (override) { ScrollTween.removeTweens(target); } return new ScrollTween(target, props, pluginData); } /** * Delete all ScrollTween animations from an object * @param target The object whose ScrollTween to be deleted * @version Egret 2.4 * @platform Web,Native * @language en_US */ /** * 删除一个对象上的全部 ScrollTween 动画 * @param target 需要移除 ScrollTween 的对象 * @version Egret 2.4 * @platform Web,Native * @language zh_CN */ public static removeTweens(target:any):void { if (!target.tween_count) { return; } let tweens:ScrollTween[] = ScrollTween._tweens; for (let i = tweens.length - 1; i >= 0; i--) { if (tweens[i]._target == target) { tweens[i].paused = true; tweens.splice(i, 1); } } target.tween_count = 0; } /** * @private * * @param delta * @param paused */ private static tick(timeStamp:number, paused = false):boolean { let delta = timeStamp - ScrollTween._lastTime; ScrollTween._lastTime = timeStamp; let tweens:ScrollTween[] = ScrollTween._tweens.concat(); for (let i = tweens.length - 1; i >= 0; i--) { let tween:ScrollTween = tweens[i]; if ((paused && !tween.ignoreGlobalPause) || tween.paused) { continue; } tween.tick(tween._useTicks ? 1 : delta); } return false; } private static _lastTime:number = 0; /** * @private * * @param tween * @param value */ private static _register(tween:ScrollTween, value:boolean):void { let target:any = tween._target; let tweens:ScrollTween[] = ScrollTween._tweens; if (value) { if (target) { target.tween_count = target.tween_count > 0 ? target.tween_count + 1 : 1; } tweens.push(tween); if (!ScrollTween._inited) { ScrollTween._lastTime = egret.getTimer(); ticker.$startTick(ScrollTween.tick, null); ScrollTween._inited = true; } } else { if (target) { target.tween_count--; } let i = tweens.length; while (i--) { if (tweens[i] == tween) { tweens.splice(i, 1); return; } } } } /** * 创建一个 egret.ScrollTween 对象 * @private * @version Egret 2.4 * @platform Web,Native */ constructor(target:any, props:any, pluginData:any) { super(); this.initialize(target, props, pluginData); } /** * @private * * @param target * @param props * @param pluginData */ private initialize(target:any, props:any, pluginData:any):void { this._target = target; if (props) { this._useTicks = props.useTicks; this.ignoreGlobalPause = props.ignoreGlobalPause; this.loop = props.loop; props.onChange && this.addEventListener("change", props.onChange, props.onChangeObj); if (props.override) { ScrollTween.removeTweens(target); } } this.pluginData = pluginData || {}; this._curQueueProps = {}; this._initQueueProps = {}; this._steps = []; this._actions = []; if (props && props.paused) { this.paused = true; } else { ScrollTween._register(this, true); } if (props && props.position != null) { this.setPosition(props.position); } } /** * @private * * @param value * @param actionsMode * @returns */ private setPosition(value:number, actionsMode:number = 1):boolean { if (value < 0) { value = 0; } //正常化位置 let t:number = value; let end:boolean = false; if (t >= this.duration) { if (this.loop) { t = t % this.duration; } else { t = this.duration; end = true; } } if (t == this._prevPos) { return end; } let prevPos = this._prevPos; this.position = this._prevPos = t; this._prevPosition = value; if (this._target) { if (end) { //结束 this._updateTargetProps(null, 1); } else if (this._steps.length > 0) { // 找到新的tween let i:number; let l = this._steps.length; for (i = 0; i < l; i++) { if (this._steps[i].t > t) { break; } } let step = this._steps[i - 1]; this._updateTargetProps(step, (this._stepPosition = t - step.t) / step.d); } } if (end) { this.setPaused(true); } //执行actions if (actionsMode != 0 && this._actions.length > 0) { if (this._useTicks) { this._runActions(t, t); } else if (actionsMode == 1 && t < prevPos) { if (prevPos != this.duration) { this._runActions(prevPos, this.duration); } this._runActions(0, t, true); } else { this._runActions(prevPos, t); } } this.dispatchEventWith("change"); return end; } /** * @private * * @param startPos * @param endPos * @param includeStart */ private _runActions(startPos:number, endPos:number, includeStart:boolean = false) { let sPos:number = startPos; let ePos:number = endPos; let i:number = -1; let j:number = this._actions.length; let k:number = 1; if (startPos > endPos) { //把所有的倒置 sPos = endPos; ePos = startPos; i = j; j = k = -1; } while ((i += k) != j) { let action = this._actions[i]; let pos = action.t; if (pos == ePos || (pos > sPos && pos < ePos) || (includeStart && pos == startPos)) { action.f.apply(action.o, action.p); } } } /** * @private * * @param step * @param ratio */ private _updateTargetProps(step:any, ratio:number) { let p0, p1, v, v0, v1, arr; if (!step && ratio == 1) { this.passive = false; p0 = p1 = this._curQueueProps; } else { this.passive = !!step.v; //不更新props. if (this.passive) { return; } //使用ease if (step.e) { ratio = step.e(ratio, 0, 1, 1); } p0 = step.p0; p1 = step.p1; } for (let n in this._initQueueProps) { if ((v0 = p0[n]) == null) { p0[n] = v0 = this._initQueueProps[n]; } if ((v1 = p1[n]) == null) { p1[n] = v1 = v0; } if (v0 == v1 || ratio == 0 || ratio == 1 || (typeof(v0) != "number")) { v = ratio == 1 ? v1 : v0; } else { v = v0 + (v1 - v0) * ratio; } let ignore = false; if (arr = ScrollTween._plugins[n]) { for (let i = 0, l = arr.length; i < l; i++) { let v2 = arr[i].tween(this, n, v, p0, p1, ratio, !!step && p0 == p1, !step); if (v2 == ScrollTween.IGNORE) { ignore = true; } else { v = v2; } } } if (!ignore) { this._target[n] = v; } } } /** * Whether setting is paused * @param value {boolean} Whether to pause * @returns ScrollTween object itself * @version Egret 2.4 * @platform Web,Native * @language en_US */ /** * 设置是否暂停 * @param value {boolean} 是否暂停 * @returns Tween对象本身 * @version Egret 2.4 * @platform Web,Native * @language zh_CN */ public setPaused(value:boolean):ScrollTween { this.paused = value; ScrollTween._register(this, !value); return this; } /** * @private * * @param props * @returns */ private _cloneProps(props):any { let o = {}; for (let n in props) { o[n] = props[n]; } return o; } /** * @private * * @param o * @returns */ private _addStep(o):ScrollTween { if (o.d > 0) { this._steps.push(o); o.t = this.duration; this.duration += o.d; } return this; } /** * @private * * @param o * @returns */ private _appendQueueProps(o):any { let arr, oldValue, i, l, injectProps; for (let n in o) { if (this._initQueueProps[n] === undefined) { oldValue = this._target[n]; //设置plugins if (arr = ScrollTween._plugins[n]) { for (i = 0, l = arr.length; i < l; i++) { oldValue = arr[i].init(this, n, oldValue); } } this._initQueueProps[n] = this._curQueueProps[n] = (oldValue === undefined) ? null : oldValue; } else { oldValue = this._curQueueProps[n]; } } for (let n in o) { oldValue = this._curQueueProps[n]; if (arr = ScrollTween._plugins[n]) { injectProps = injectProps || {}; for (i = 0, l = arr.length; i < l; i++) { if (arr[i].step) { arr[i].step(this, n, oldValue, o[n], injectProps); } } } this._curQueueProps[n] = o[n]; } if (injectProps) { this._appendQueueProps(injectProps); } return this._curQueueProps; } /** * @private * * @param o * @returns */ private _addAction(o):ScrollTween { o.t = this.duration; this._actions.push(o); return this; } /** * Modify the property of the specified display object to a specified value * @param props {Object} Property set of an object * @param duration {number} Duration * @param ease {egret.ScrollEase} Easing algorithm * @returns {egret.ScrollTween} ScrollTween object itself * @version Egret 2.4 * @platform Web,Native * @language en_US */ /** * 将指定显示对象的属性修改为指定值 * @param props {Object} 对象的属性集合 * @param duration {number} 持续时间 * @param ease {egret.ScrollEase} 缓动算法 * @returns {egret.ScrollTween} Tween对象本身 * @version Egret 2.4 * @platform Web,Native * @language zh_CN */ public to(props, duration?:number, ease:Function = undefined):ScrollTween { if (isNaN(duration) || duration < 0) { duration = 0; } return this._addStep({d: duration || 0, p0: this._cloneProps(this._curQueueProps), e: ease, p1: this._cloneProps(this._appendQueueProps(props))}); } /** * Execute callback function * @param callback {Function} Callback method * @param thisObj {any} this action scope of the callback method * @param params {any[]} Parameter of the callback method * @returns {egret.ScrollTween} ScrollTween object itself * @version Egret 2.4 * @platform Web,Native * @language en_US */ /** * 执行回调函数 * @param callback {Function} 回调方法 * @param thisObj {any} 回调方法this作用域 * @param params {any[]} 回调方法参数 * @returns {egret.ScrollTween} Tween对象本身 * @version Egret 2.4 * @platform Web,Native * @language zh_CN */ public call(callback:Function, thisObj:any = undefined, params:any[] = undefined):ScrollTween { return this._addAction({f: callback, p: params ? params : [], o: thisObj ? thisObj : this._target}); } /** * @method egret.ScrollTween#tick * @param delta {number} * @private * @version Egret 2.4 * @platform Web,Native */ public tick(delta:number):void { if (this.paused) { return; } this.setPosition(this._prevPosition + delta); } } }