| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 | 
							- var Clip = require("./Clip");
 
- var _util = require("../core/util");
 
- var isArrayLike = _util.isArrayLike;
 
- var color = require("../tool/color");
 
- var arraySlice = Array.prototype.slice;
 
- /**
 
-  * @param {Object} target
 
-  * @param {string} propName
 
-  * @param {Array.<Object>} keyframes
 
-  *        [{
 
-  *            time: number,
 
-  *            value: number | color string | Array.<number> | Array.<Array.<number>>
 
-  *        }, ...]
 
-  *        [Caveat]:
 
-  *        (1) The order should ensured by time.
 
-  *        (2) If `value` is `Array`, it must not be shared outside (espaciall el.shape, el.style),
 
-  *        in case that it be modified outside and cause incorrect interpolate result.
 
-  * @param {string} easing
 
-  * @param {boolean} [delay=false]
 
-  * @param {boolean} [loop=false]
 
-  * @param {boolean} [forceAnimate=false]
 
-  * @param {Function} [getter=defaultGetter]
 
-  * @param {Function} [setter=defaultSetter]
 
-  * @return {module:zrender/animation/Clip} clip
 
-  */
 
- function createTrackClip(target, propName, keyframes, easing, delay, loop, forceAnimate, getter, setter) {
 
-   var useSpline = easing === 'spline';
 
-   getter = getter || defaultGetter;
 
-   setter = setter || defaultSetter;
 
-   var trackLen = keyframes.length;
 
-   if (!trackLen) {
 
-     return;
 
-   } // Guess data type
 
-   var firstVal = keyframes[0].value;
 
-   var isValueArray = isArrayLike(firstVal);
 
-   var isValueColor = false;
 
-   var isValueString = false; // For vertices morphing
 
-   var arrDim = isValueArray ? getArrayDim(keyframes) : 0;
 
-   var trackMaxTime;
 
-   trackMaxTime = keyframes[trackLen - 1].time; // Percents of each keyframe
 
-   var kfPercents = []; // Value of each keyframe
 
-   var kfValues = [];
 
-   var prevValue = keyframes[0].value;
 
-   var isAllValueEqual = true;
 
-   for (var i = 0; i < trackLen; i++) {
 
-     kfPercents.push(keyframes[i].time / trackMaxTime); // Assume value is a color when it is a string
 
-     var value = keyframes[i].value; // Check if value is equal, deep check if value is array
 
-     if (!(isValueArray && isArraySame(value, prevValue, arrDim) || !isValueArray && value === prevValue)) {
 
-       isAllValueEqual = false;
 
-     }
 
-     prevValue = value; // Try converting a string to a color array
 
-     if (typeof value === 'string') {
 
-       var colorArray = color.parse(value);
 
-       if (colorArray) {
 
-         value = colorArray;
 
-         isValueColor = true;
 
-       } else {
 
-         isValueString = true;
 
-       }
 
-     }
 
-     kfValues.push(value);
 
-   }
 
-   if (!forceAnimate && isAllValueEqual) {
 
-     return;
 
-   }
 
-   var lastValue = kfValues[trackLen - 1]; // Polyfill array and NaN value
 
-   for (var i = 0; i < trackLen - 1; i++) {
 
-     if (isValueArray) {
 
-       fillArr(kfValues[i], lastValue, arrDim);
 
-     } else {
 
-       if (isNaN(kfValues[i]) && !isNaN(lastValue) && !isValueString && !isValueColor) {
 
-         kfValues[i] = lastValue;
 
-       }
 
-     }
 
-   }
 
-   isValueArray && fillArr(getter(target, propName), lastValue, arrDim); // Cache the key of last frame to speed up when
 
-   // animation playback is sequency
 
-   var lastFrame = 0;
 
-   var lastFramePercent = 0;
 
-   var start;
 
-   var w;
 
-   var p0;
 
-   var p1;
 
-   var p2;
 
-   var p3;
 
-   if (isValueColor) {
 
-     var rgba = [0, 0, 0, 0];
 
-   }
 
-   function hanleFrame(target, percent) {
 
-     // Find the range keyframes
 
-     // kf1-----kf2---------current--------kf3
 
-     // find kf2 and kf3 and do interpolation
 
-     var frame; // In the easing function like elasticOut, percent may less than 0
 
-     if (percent < 0) {
 
-       frame = 0;
 
-     } else if (percent < lastFramePercent) {
 
-       // Start from next key
 
-       // PENDING start from lastFrame ?
 
-       start = Math.min(lastFrame + 1, trackLen - 1);
 
-       for (frame = start; frame >= 0; frame--) {
 
-         if (kfPercents[frame] <= percent) {
 
-           break;
 
-         }
 
-       } // PENDING really need to do this ?
 
-       frame = Math.min(frame, trackLen - 2);
 
-     } else {
 
-       for (frame = lastFrame; frame < trackLen; frame++) {
 
-         if (kfPercents[frame] > percent) {
 
-           break;
 
-         }
 
-       }
 
-       frame = Math.min(frame - 1, trackLen - 2);
 
-     }
 
-     lastFrame = frame;
 
-     lastFramePercent = percent;
 
-     var range = kfPercents[frame + 1] - kfPercents[frame];
 
-     if (range === 0) {
 
-       return;
 
-     } else {
 
-       w = (percent - kfPercents[frame]) / range;
 
-     }
 
-     if (useSpline) {
 
-       p1 = kfValues[frame];
 
-       p0 = kfValues[frame === 0 ? frame : frame - 1];
 
-       p2 = kfValues[frame > trackLen - 2 ? trackLen - 1 : frame + 1];
 
-       p3 = kfValues[frame > trackLen - 3 ? trackLen - 1 : frame + 2];
 
-       if (isValueArray) {
 
-         catmullRomInterpolateArray(p0, p1, p2, p3, w, w * w, w * w * w, getter(target, propName), arrDim);
 
-       } else {
 
-         var value;
 
-         if (isValueColor) {
 
-           value = catmullRomInterpolateArray(p0, p1, p2, p3, w, w * w, w * w * w, rgba, 1);
 
-           value = rgba2String(rgba);
 
-         } else if (isValueString) {
 
-           // String is step(0.5)
 
-           return interpolateString(p1, p2, w);
 
-         } else {
 
-           value = catmullRomInterpolate(p0, p1, p2, p3, w, w * w, w * w * w);
 
-         }
 
-         setter(target, propName, value);
 
-       }
 
-     } else {
 
-       if (isValueArray) {
 
-         interpolateArray(kfValues[frame], kfValues[frame + 1], w, getter(target, propName), arrDim);
 
-       } else {
 
-         var value;
 
-         if (isValueColor) {
 
-           interpolateArray(kfValues[frame], kfValues[frame + 1], w, rgba, 1);
 
-           value = rgba2String(rgba);
 
-         } else if (isValueString) {
 
-           // String is step(0.5)
 
-           return interpolateString(kfValues[frame], kfValues[frame + 1], w);
 
-         } else {
 
-           value = interpolateNumber(kfValues[frame], kfValues[frame + 1], w);
 
-         }
 
-         if (target.aaaa != null) {
 
-           console.log(target.uuid, value, propName);
 
-         }
 
-         setter(target, propName, value);
 
-       }
 
-     }
 
-   }
 
-   var clip = new Clip({
 
-     target: target,
 
-     life: trackMaxTime,
 
-     loop: loop,
 
-     delay: delay,
 
-     onframe: hanleFrame
 
-   });
 
-   if (easing && easing !== 'spline') {
 
-     clip.easing = easing;
 
-   }
 
-   return clip;
 
- }
 
- function getArrayDim(keyframes) {
 
-   var lastValue = keyframes[keyframes.length - 1].value;
 
-   return isArrayLike(lastValue && lastValue[0]) ? 2 : 1;
 
- }
 
- /**
 
-  * @param  {Array} arr0
 
-  * @param  {Array} arr1
 
-  * @param  {number} arrDim
 
-  * @return {boolean}
 
-  */
 
- function isArraySame(arr0, arr1, arrDim) {
 
-   if (arr0 === arr1) {
 
-     return true;
 
-   }
 
-   var len = arr0.length;
 
-   if (len !== arr1.length) {
 
-     return false;
 
-   }
 
-   if (arrDim === 1) {
 
-     for (var i = 0; i < len; i++) {
 
-       if (arr0[i] !== arr1[i]) {
 
-         return false;
 
-       }
 
-     }
 
-   } else {
 
-     var len2 = arr0[0].length;
 
-     for (var i = 0; i < len; i++) {
 
-       for (var j = 0; j < len2; j++) {
 
-         if (arr0[i][j] !== arr1[i][j]) {
 
-           return false;
 
-         }
 
-       }
 
-     }
 
-   }
 
-   return true;
 
- } // arr0 is source array, arr1 is target array.
 
- // Do some preprocess to avoid error happened when interpolating from arr0 to arr1
 
- function fillArr(arr0, arr1, arrDim) {
 
-   var arr0Len = arr0.length;
 
-   var arr1Len = arr1.length;
 
-   if (arr0Len !== arr1Len) {
 
-     // FIXME Not work for TypedArray
 
-     var isPreviousLarger = arr0Len > arr1Len;
 
-     if (isPreviousLarger) {
 
-       // Cut the previous
 
-       arr0.length = arr1Len;
 
-     } else {
 
-       // Fill the previous
 
-       for (var i = arr0Len; i < arr1Len; i++) {
 
-         arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]));
 
-       }
 
-     }
 
-   } // Handling NaN value
 
-   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];
 
-         }
 
-       }
 
-     }
 
-   }
 
- }
 
- /**
 
-  * Catmull Rom interpolate array
 
-  * @param  {Array} p0
 
-  * @param  {Array} p1
 
-  * @param  {Array} p2
 
-  * @param  {Array} p3
 
-  * @param  {number} t
 
-  * @param  {number} t2
 
-  * @param  {number} t3
 
-  * @param  {Array} out
 
-  * @param  {number} arrDim
 
-  */
 
- function catmullRomInterpolateArray(p0, p1, p2, p3, t, t2, t3, out, arrDim) {
 
-   var len = p0.length;
 
-   if (arrDim === 1) {
 
-     for (var i = 0; i < len; i++) {
 
-       out[i] = catmullRomInterpolate(p0[i], p1[i], p2[i], p3[i], t, t2, t3);
 
-     }
 
-   } else {
 
-     var len2 = p0[0].length;
 
-     for (var i = 0; i < len; i++) {
 
-       for (var j = 0; j < len2; j++) {
 
-         out[i][j] = catmullRomInterpolate(p0[i][j], p1[i][j], p2[i][j], p3[i][j], t, t2, t3);
 
-       }
 
-     }
 
-   }
 
- }
 
- /**
 
-  * Catmull Rom interpolate number
 
-  * @param  {number} p0
 
-  * @param  {number} p1
 
-  * @param  {number} p2
 
-  * @param  {number} p3
 
-  * @param  {number} t
 
-  * @param  {number} t2
 
-  * @param  {number} t3
 
-  * @return {number}
 
-  */
 
- function catmullRomInterpolate(p0, p1, p2, p3, t, t2, t3) {
 
-   var v0 = (p2 - p0) * 0.5;
 
-   var v1 = (p3 - p1) * 0.5;
 
-   return (2 * (p1 - p2) + v0 + v1) * t3 + (-3 * (p1 - p2) - 2 * v0 - v1) * t2 + v0 * t + p1;
 
- }
 
- /**
 
-  * @param  {number} p0
 
-  * @param  {number} p1
 
-  * @param  {number} percent
 
-  * @return {number}
 
-  */
 
- function interpolateNumber(p0, p1, percent) {
 
-   return (p1 - p0) * percent + p0;
 
- }
 
- /**
 
-  * @param  {string} p0
 
-  * @param  {string} p1
 
-  * @param  {number} percent
 
-  * @return {string}
 
-  */
 
- function interpolateString(p0, p1, percent) {
 
-   return percent > 0.5 ? p1 : p0;
 
- }
 
- /**
 
-  * @param  {Array} p0
 
-  * @param  {Array} p1
 
-  * @param  {number} percent
 
-  * @param  {Array} out
 
-  * @param  {number} arrDim
 
-  */
 
- function interpolateArray(p0, p1, percent, out, arrDim) {
 
-   var len = p0.length;
 
-   if (arrDim === 1) {
 
-     for (var i = 0; i < len; i++) {
 
-       out[i] = interpolateNumber(p0[i], p1[i], percent);
 
-     }
 
-   } else {
 
-     var len2 = len && p0[0].length;
 
-     for (var i = 0; i < len; i++) {
 
-       for (var j = 0; j < len2; j++) {
 
-         out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent);
 
-       }
 
-     }
 
-   }
 
- }
 
- function rgba2String(rgba) {
 
-   rgba[0] = Math.floor(rgba[0]);
 
-   rgba[1] = Math.floor(rgba[1]);
 
-   rgba[2] = Math.floor(rgba[2]);
 
-   return 'rgba(' + rgba.join(',') + ')';
 
- }
 
- function cloneFrameValue(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 defaultGetter(target, key) {
 
-   return target[key];
 
- }
 
- function defaultSetter(target, key, value) {
 
-   target[key] = value;
 
- }
 
- exports.createTrackClip = createTrackClip;
 
- exports.cloneFrameValue = cloneFrameValue;
 
- exports.defaultGetter = defaultGetter;
 
- exports.defaultSetter = defaultSetter;
 
 
  |