| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737 | import Clip from './Clip.js';import * as color from '../tool/color.js';import { eqNaN, extend, isArrayLike, isFunction, isGradientObject, isNumber, isString, keys, logError, map } from '../core/util.js';import easingFuncs from './easing.js';import { createCubicEasingFunc } from './cubicEasing.js';import { isLinearGradient, isRadialGradient } from '../svg/helper.js';;var arraySlice = Array.prototype.slice;function interpolateNumber(p0, p1, percent) {    return (p1 - p0) * percent + p0;}function interpolate1DArray(out, p0, p1, percent) {    var len = p0.length;    for (var i = 0; i < len; i++) {        out[i] = interpolateNumber(p0[i], p1[i], percent);    }    return out;}function interpolate2DArray(out, p0, p1, percent) {    var len = p0.length;    var len2 = len && p0[0].length;    for (var i = 0; i < len; i++) {        if (!out[i]) {            out[i] = [];        }        for (var j = 0; j < len2; j++) {            out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent);        }    }    return out;}function add1DArray(out, p0, p1, sign) {    var len = p0.length;    for (var i = 0; i < len; i++) {        out[i] = p0[i] + p1[i] * sign;    }    return out;}function add2DArray(out, p0, p1, sign) {    var len = p0.length;    var len2 = len && p0[0].length;    for (var i = 0; i < len; i++) {        if (!out[i]) {            out[i] = [];        }        for (var j = 0; j < len2; j++) {            out[i][j] = p0[i][j] + p1[i][j] * sign;        }    }    return out;}function fillColorStops(val0, val1) {    var len0 = val0.length;    var len1 = val1.length;    var shorterArr = len0 > len1 ? val1 : val0;    var shorterLen = Math.min(len0, len1);    var last = shorterArr[shorterLen - 1] || { color: [0, 0, 0, 0], offset: 0 };    for (var i = shorterLen; i < Math.max(len0, len1); i++) {        shorterArr.push({            offset: last.offset,            color: last.color.slice()        });    }}function fillArray(val0, val1, arrDim) {    var arr0 = val0;    var arr1 = val1;    if (!arr0.push || !arr1.push) {        return;    }    var arr0Len = arr0.length;    var arr1Len = arr1.length;    if (arr0Len !== arr1Len) {        var isPreviousLarger = arr0Len > arr1Len;        if (isPreviousLarger) {            arr0.length = arr1Len;        }        else {            for (var i = arr0Len; i < arr1Len; i++) {                arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]));            }        }    }    var len2 = arr0[0] && arr0[0].length;    for (var i = 0; i < arr0.length; i++) {        if (arrDim === 1) {            if (isNaN(arr0[i])) {                arr0[i] = arr1[i];            }        }        else {            for (var j = 0; j < len2; j++) {                if (isNaN(arr0[i][j])) {                    arr0[i][j] = arr1[i][j];                }            }        }    }}export function cloneValue(value) {    if (isArrayLike(value)) {        var len = value.length;        if (isArrayLike(value[0])) {            var ret = [];            for (var i = 0; i < len; i++) {                ret.push(arraySlice.call(value[i]));            }            return ret;        }        return arraySlice.call(value);    }    return value;}function rgba2String(rgba) {    rgba[0] = Math.floor(rgba[0]) || 0;    rgba[1] = Math.floor(rgba[1]) || 0;    rgba[2] = Math.floor(rgba[2]) || 0;    rgba[3] = rgba[3] == null ? 1 : rgba[3];    return 'rgba(' + rgba.join(',') + ')';}function guessArrayDim(value) {    return isArrayLike(value && value[0]) ? 2 : 1;}var VALUE_TYPE_NUMBER = 0;var VALUE_TYPE_1D_ARRAY = 1;var VALUE_TYPE_2D_ARRAY = 2;var VALUE_TYPE_COLOR = 3;var VALUE_TYPE_LINEAR_GRADIENT = 4;var VALUE_TYPE_RADIAL_GRADIENT = 5;var VALUE_TYPE_UNKOWN = 6;function isGradientValueType(valType) {    return valType === VALUE_TYPE_LINEAR_GRADIENT || valType === VALUE_TYPE_RADIAL_GRADIENT;}function isArrayValueType(valType) {    return valType === VALUE_TYPE_1D_ARRAY || valType === VALUE_TYPE_2D_ARRAY;}var tmpRgba = [0, 0, 0, 0];var Track = (function () {    function Track(propName) {        this.keyframes = [];        this.discrete = false;        this._invalid = false;        this._needsSort = false;        this._lastFr = 0;        this._lastFrP = 0;        this.propName = propName;    }    Track.prototype.isFinished = function () {        return this._finished;    };    Track.prototype.setFinished = function () {        this._finished = true;        if (this._additiveTrack) {            this._additiveTrack.setFinished();        }    };    Track.prototype.needsAnimate = function () {        return this.keyframes.length >= 1;    };    Track.prototype.getAdditiveTrack = function () {        return this._additiveTrack;    };    Track.prototype.addKeyframe = function (time, rawValue, easing) {        this._needsSort = true;        var keyframes = this.keyframes;        var len = keyframes.length;        var discrete = false;        var valType = VALUE_TYPE_UNKOWN;        var value = rawValue;        if (isArrayLike(rawValue)) {            var arrayDim = guessArrayDim(rawValue);            valType = arrayDim;            if (arrayDim === 1 && !isNumber(rawValue[0])                || arrayDim === 2 && !isNumber(rawValue[0][0])) {                discrete = true;            }        }        else {            if (isNumber(rawValue) && !eqNaN(rawValue)) {                valType = VALUE_TYPE_NUMBER;            }            else if (isString(rawValue)) {                if (!isNaN(+rawValue)) {                    valType = VALUE_TYPE_NUMBER;                }                else {                    var colorArray = color.parse(rawValue);                    if (colorArray) {                        value = colorArray;                        valType = VALUE_TYPE_COLOR;                    }                }            }            else if (isGradientObject(rawValue)) {                var parsedGradient = extend({}, value);                parsedGradient.colorStops = map(rawValue.colorStops, function (colorStop) { return ({                    offset: colorStop.offset,                    color: color.parse(colorStop.color)                }); });                if (isLinearGradient(rawValue)) {                    valType = VALUE_TYPE_LINEAR_GRADIENT;                }                else if (isRadialGradient(rawValue)) {                    valType = VALUE_TYPE_RADIAL_GRADIENT;                }                value = parsedGradient;            }        }        if (len === 0) {            this.valType = valType;        }        else if (valType !== this.valType || valType === VALUE_TYPE_UNKOWN) {            discrete = true;        }        this.discrete = this.discrete || discrete;        var kf = {            time: time,            value: value,            rawValue: rawValue,            percent: 0        };        if (easing) {            kf.easing = easing;            kf.easingFunc = isFunction(easing)                ? easing                : easingFuncs[easing] || createCubicEasingFunc(easing);        }        keyframes.push(kf);        return kf;    };    Track.prototype.prepare = function (maxTime, additiveTrack) {        var kfs = this.keyframes;        if (this._needsSort) {            kfs.sort(function (a, b) {                return a.time - b.time;            });        }        var valType = this.valType;        var kfsLen = kfs.length;        var lastKf = kfs[kfsLen - 1];        var isDiscrete = this.discrete;        var isArr = isArrayValueType(valType);        var isGradient = isGradientValueType(valType);        for (var i = 0; i < kfsLen; i++) {            var kf = kfs[i];            var value = kf.value;            var lastValue = lastKf.value;            kf.percent = kf.time / maxTime;            if (!isDiscrete) {                if (isArr && i !== kfsLen - 1) {                    fillArray(value, lastValue, valType);                }                else if (isGradient) {                    fillColorStops(value.colorStops, lastValue.colorStops);                }            }        }        if (!isDiscrete            && valType !== VALUE_TYPE_RADIAL_GRADIENT            && additiveTrack            && this.needsAnimate()            && additiveTrack.needsAnimate()            && valType === additiveTrack.valType            && !additiveTrack._finished) {            this._additiveTrack = additiveTrack;            var startValue = kfs[0].value;            for (var i = 0; i < kfsLen; i++) {                if (valType === VALUE_TYPE_NUMBER) {                    kfs[i].additiveValue = kfs[i].value - startValue;                }                else if (valType === VALUE_TYPE_COLOR) {                    kfs[i].additiveValue =                        add1DArray([], kfs[i].value, startValue, -1);                }                else if (isArrayValueType(valType)) {                    kfs[i].additiveValue = valType === VALUE_TYPE_1D_ARRAY                        ? add1DArray([], kfs[i].value, startValue, -1)                        : add2DArray([], kfs[i].value, startValue, -1);                }            }        }    };    Track.prototype.step = function (target, percent) {        if (this._finished) {            return;        }        if (this._additiveTrack && this._additiveTrack._finished) {            this._additiveTrack = null;        }        var isAdditive = this._additiveTrack != null;        var valueKey = isAdditive ? 'additiveValue' : 'value';        var valType = this.valType;        var keyframes = this.keyframes;        var kfsNum = keyframes.length;        var propName = this.propName;        var isValueColor = valType === VALUE_TYPE_COLOR;        var frameIdx;        var lastFrame = this._lastFr;        var mathMin = Math.min;        var frame;        var nextFrame;        if (kfsNum === 1) {            frame = nextFrame = keyframes[0];        }        else {            if (percent < 0) {                frameIdx = 0;            }            else if (percent < this._lastFrP) {                var start = mathMin(lastFrame + 1, kfsNum - 1);                for (frameIdx = start; frameIdx >= 0; frameIdx--) {                    if (keyframes[frameIdx].percent <= percent) {                        break;                    }                }                frameIdx = mathMin(frameIdx, kfsNum - 2);            }            else {                for (frameIdx = lastFrame; frameIdx < kfsNum; frameIdx++) {                    if (keyframes[frameIdx].percent > percent) {                        break;                    }                }                frameIdx = mathMin(frameIdx - 1, kfsNum - 2);            }            nextFrame = keyframes[frameIdx + 1];            frame = keyframes[frameIdx];        }        if (!(frame && nextFrame)) {            return;        }        this._lastFr = frameIdx;        this._lastFrP = percent;        var interval = (nextFrame.percent - frame.percent);        var w = interval === 0 ? 1 : mathMin((percent - frame.percent) / interval, 1);        if (nextFrame.easingFunc) {            w = nextFrame.easingFunc(w);        }        var targetArr = isAdditive ? this._additiveValue            : (isValueColor ? tmpRgba : target[propName]);        if ((isArrayValueType(valType) || isValueColor) && !targetArr) {            targetArr = this._additiveValue = [];        }        if (this.discrete) {            target[propName] = w < 1 ? frame.rawValue : nextFrame.rawValue;        }        else if (isArrayValueType(valType)) {            valType === VALUE_TYPE_1D_ARRAY                ? interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w)                : interpolate2DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);        }        else if (isGradientValueType(valType)) {            var val = frame[valueKey];            var nextVal_1 = nextFrame[valueKey];            var isLinearGradient_1 = valType === VALUE_TYPE_LINEAR_GRADIENT;            target[propName] = {                type: isLinearGradient_1 ? 'linear' : 'radial',                x: interpolateNumber(val.x, nextVal_1.x, w),                y: interpolateNumber(val.y, nextVal_1.y, w),                colorStops: map(val.colorStops, function (colorStop, idx) {                    var nextColorStop = nextVal_1.colorStops[idx];                    return {                        offset: interpolateNumber(colorStop.offset, nextColorStop.offset, w),                        color: rgba2String(interpolate1DArray([], colorStop.color, nextColorStop.color, w))                    };                }),                global: nextVal_1.global            };            if (isLinearGradient_1) {                target[propName].x2 = interpolateNumber(val.x2, nextVal_1.x2, w);                target[propName].y2 = interpolateNumber(val.y2, nextVal_1.y2, w);            }            else {                target[propName].r = interpolateNumber(val.r, nextVal_1.r, w);            }        }        else if (isValueColor) {            interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);            if (!isAdditive) {                target[propName] = rgba2String(targetArr);            }        }        else {            var value = interpolateNumber(frame[valueKey], nextFrame[valueKey], w);            if (isAdditive) {                this._additiveValue = value;            }            else {                target[propName] = value;            }        }        if (isAdditive) {            this._addToTarget(target);        }    };    Track.prototype._addToTarget = function (target) {        var valType = this.valType;        var propName = this.propName;        var additiveValue = this._additiveValue;        if (valType === VALUE_TYPE_NUMBER) {            target[propName] = target[propName] + additiveValue;        }        else if (valType === VALUE_TYPE_COLOR) {            color.parse(target[propName], tmpRgba);            add1DArray(tmpRgba, tmpRgba, additiveValue, 1);            target[propName] = rgba2String(tmpRgba);        }        else if (valType === VALUE_TYPE_1D_ARRAY) {            add1DArray(target[propName], target[propName], additiveValue, 1);        }        else if (valType === VALUE_TYPE_2D_ARRAY) {            add2DArray(target[propName], target[propName], additiveValue, 1);        }    };    return Track;}());var Animator = (function () {    function Animator(target, loop, allowDiscreteAnimation, additiveTo) {        this._tracks = {};        this._trackKeys = [];        this._maxTime = 0;        this._started = 0;        this._clip = null;        this._target = target;        this._loop = loop;        if (loop && additiveTo) {            logError('Can\' use additive animation on looped animation.');            return;        }        this._additiveAnimators = additiveTo;        this._allowDiscrete = allowDiscreteAnimation;    }    Animator.prototype.getMaxTime = function () {        return this._maxTime;    };    Animator.prototype.getDelay = function () {        return this._delay;    };    Animator.prototype.getLoop = function () {        return this._loop;    };    Animator.prototype.getTarget = function () {        return this._target;    };    Animator.prototype.changeTarget = function (target) {        this._target = target;    };    Animator.prototype.when = function (time, props, easing) {        return this.whenWithKeys(time, props, keys(props), easing);    };    Animator.prototype.whenWithKeys = function (time, props, propNames, easing) {        var tracks = this._tracks;        for (var i = 0; i < propNames.length; i++) {            var propName = propNames[i];            var track = tracks[propName];            if (!track) {                track = tracks[propName] = new Track(propName);                var initialValue = void 0;                var additiveTrack = this._getAdditiveTrack(propName);                if (additiveTrack) {                    var addtiveTrackKfs = additiveTrack.keyframes;                    var lastFinalKf = addtiveTrackKfs[addtiveTrackKfs.length - 1];                    initialValue = lastFinalKf && lastFinalKf.value;                    if (additiveTrack.valType === VALUE_TYPE_COLOR && initialValue) {                        initialValue = rgba2String(initialValue);                    }                }                else {                    initialValue = this._target[propName];                }                if (initialValue == null) {                    continue;                }                if (time > 0) {                    track.addKeyframe(0, cloneValue(initialValue), easing);                }                this._trackKeys.push(propName);            }            track.addKeyframe(time, cloneValue(props[propName]), easing);        }        this._maxTime = Math.max(this._maxTime, time);        return this;    };    Animator.prototype.pause = function () {        this._clip.pause();        this._paused = true;    };    Animator.prototype.resume = function () {        this._clip.resume();        this._paused = false;    };    Animator.prototype.isPaused = function () {        return !!this._paused;    };    Animator.prototype.duration = function (duration) {        this._maxTime = duration;        this._force = true;        return this;    };    Animator.prototype._doneCallback = function () {        this._setTracksFinished();        this._clip = null;        var doneList = this._doneCbs;        if (doneList) {            var len = doneList.length;            for (var i = 0; i < len; i++) {                doneList[i].call(this);            }        }    };    Animator.prototype._abortedCallback = function () {        this._setTracksFinished();        var animation = this.animation;        var abortedList = this._abortedCbs;        if (animation) {            animation.removeClip(this._clip);        }        this._clip = null;        if (abortedList) {            for (var i = 0; i < abortedList.length; i++) {                abortedList[i].call(this);            }        }    };    Animator.prototype._setTracksFinished = function () {        var tracks = this._tracks;        var tracksKeys = this._trackKeys;        for (var i = 0; i < tracksKeys.length; i++) {            tracks[tracksKeys[i]].setFinished();        }    };    Animator.prototype._getAdditiveTrack = function (trackName) {        var additiveTrack;        var additiveAnimators = this._additiveAnimators;        if (additiveAnimators) {            for (var i = 0; i < additiveAnimators.length; i++) {                var track = additiveAnimators[i].getTrack(trackName);                if (track) {                    additiveTrack = track;                }            }        }        return additiveTrack;    };    Animator.prototype.start = function (easing) {        if (this._started > 0) {            return;        }        this._started = 1;        var self = this;        var tracks = [];        var maxTime = this._maxTime || 0;        for (var i = 0; i < this._trackKeys.length; i++) {            var propName = this._trackKeys[i];            var track = this._tracks[propName];            var additiveTrack = this._getAdditiveTrack(propName);            var kfs = track.keyframes;            var kfsNum = kfs.length;            track.prepare(maxTime, additiveTrack);            if (track.needsAnimate()) {                if (!this._allowDiscrete && track.discrete) {                    var lastKf = kfs[kfsNum - 1];                    if (lastKf) {                        self._target[track.propName] = lastKf.rawValue;                    }                    track.setFinished();                }                else {                    tracks.push(track);                }            }        }        if (tracks.length || this._force) {            var clip = new Clip({                life: maxTime,                loop: this._loop,                delay: this._delay || 0,                onframe: function (percent) {                    self._started = 2;                    var additiveAnimators = self._additiveAnimators;                    if (additiveAnimators) {                        var stillHasAdditiveAnimator = false;                        for (var i = 0; i < additiveAnimators.length; i++) {                            if (additiveAnimators[i]._clip) {                                stillHasAdditiveAnimator = true;                                break;                            }                        }                        if (!stillHasAdditiveAnimator) {                            self._additiveAnimators = null;                        }                    }                    for (var i = 0; i < tracks.length; i++) {                        tracks[i].step(self._target, percent);                    }                    var onframeList = self._onframeCbs;                    if (onframeList) {                        for (var i = 0; i < onframeList.length; i++) {                            onframeList[i](self._target, percent);                        }                    }                },                ondestroy: function () {                    self._doneCallback();                }            });            this._clip = clip;            if (this.animation) {                this.animation.addClip(clip);            }            if (easing) {                clip.setEasing(easing);            }        }        else {            this._doneCallback();        }        return this;    };    Animator.prototype.stop = function (forwardToLast) {        if (!this._clip) {            return;        }        var clip = this._clip;        if (forwardToLast) {            clip.onframe(1);        }        this._abortedCallback();    };    Animator.prototype.delay = function (time) {        this._delay = time;        return this;    };    Animator.prototype.during = function (cb) {        if (cb) {            if (!this._onframeCbs) {                this._onframeCbs = [];            }            this._onframeCbs.push(cb);        }        return this;    };    Animator.prototype.done = function (cb) {        if (cb) {            if (!this._doneCbs) {                this._doneCbs = [];            }            this._doneCbs.push(cb);        }        return this;    };    Animator.prototype.aborted = function (cb) {        if (cb) {            if (!this._abortedCbs) {                this._abortedCbs = [];            }            this._abortedCbs.push(cb);        }        return this;    };    Animator.prototype.getClip = function () {        return this._clip;    };    Animator.prototype.getTrack = function (propName) {        return this._tracks[propName];    };    Animator.prototype.getTracks = function () {        var _this = this;        return map(this._trackKeys, function (key) { return _this._tracks[key]; });    };    Animator.prototype.stopTracks = function (propNames, forwardToLast) {        if (!propNames.length || !this._clip) {            return true;        }        var tracks = this._tracks;        var tracksKeys = this._trackKeys;        for (var i = 0; i < propNames.length; i++) {            var track = tracks[propNames[i]];            if (track && !track.isFinished()) {                if (forwardToLast) {                    track.step(this._target, 1);                }                else if (this._started === 1) {                    track.step(this._target, 0);                }                track.setFinished();            }        }        var allAborted = true;        for (var i = 0; i < tracksKeys.length; i++) {            if (!tracks[tracksKeys[i]].isFinished()) {                allAborted = false;                break;            }        }        if (allAborted) {            this._abortedCallback();        }        return allAborted;    };    Animator.prototype.saveTo = function (target, trackKeys, firstOrLast) {        if (!target) {            return;        }        trackKeys = trackKeys || this._trackKeys;        for (var i = 0; i < trackKeys.length; i++) {            var propName = trackKeys[i];            var track = this._tracks[propName];            if (!track || track.isFinished()) {                continue;            }            var kfs = track.keyframes;            var kf = kfs[firstOrLast ? 0 : kfs.length - 1];            if (kf) {                target[propName] = cloneValue(kf.rawValue);            }        }    };    Animator.prototype.__changeFinalValue = function (finalProps, trackKeys) {        trackKeys = trackKeys || keys(finalProps);        for (var i = 0; i < trackKeys.length; i++) {            var propName = trackKeys[i];            var track = this._tracks[propName];            if (!track) {                continue;            }            var kfs = track.keyframes;            if (kfs.length > 1) {                var lastKf = kfs.pop();                track.addKeyframe(lastKf.time, finalProps[propName]);                track.prepare(this._maxTime, track.getAdditiveTrack());            }        }    };    return Animator;}());export default Animator;
 |