执行动画
@param  {Object}   toProps  动画最终状态
@param  {Number}   duration 动画执行时间
@param  {String}   easing   动画缓动效果
@param  {Function} callback 动画执行后的回调
@param  {Number}   delay    动画延迟时间
500091
function animate(toProps, duration, easing, callback) {
    var delay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;

    var self = this;
    self.set('animating', true);
    var timeline = self.get('timeline');
    if (!timeline) {
      timeline = self.get('canvas').get('timeline');
      self.setSilent('timeline', timeline);
    }
    var animators = self.get('animators') || [];
    // 初始化tick
    if (!timeline._timer) {
      timeline.initTimer();
    }
    if (Util.isNumber(callback)) {
      delay = callback;
      callback = null;
    }
    if (Util.isFunction(easing)) {
      callback = easing;
      easing = 'easeLinear';
    } else {
      easing = easing ? easing : 'easeLinear';
    }
    var formatProps = getFormatProps(toProps, self);

    // 记录动画属性
    var animator = {
      fromAttrs: getFromAttrs(formatProps, self),
      toAttrs: formatProps.attrs,
      fromMatrix: Util.clone(self.getMatrix()),
      toMatrix: formatProps.matrix,
      duration: duration,
      easing: easing,
      callback: callback,
      delay: delay,
      startTime: timeline.getTime(),
      id: Util.uniqueId()
    };
    // 如果动画队列中已经有这个图形了
    if (animators.length > 0) {
      // 先检查是否需要合并属性。若有相同的动画，将该属性从前一个动画中删除,直接用后一个动画中
      animators = checkExistedAttrs(animators, animator);
    } else {
      // 否则将图形添加到队列
      timeline.addAnimator(self);
    }
    animators.push(animator);
    self.setSilent('animators', animators);
    self.setSilent('pause', { isPaused: false });
  }
1186886
function throttle (callback, wait, options) {
  var args, context
  var opts = options || {}
  var runFlag = false
  var timeout = 0
  var optLeading = 'leading' in opts ? opts.leading : true
  var optTrailing = 'trailing' in opts ? opts.trailing : false
  var runFn = function () {
    runFlag = true
    callback.apply(context, args)
    timeout = setTimeout(endFn, wait)
  }
  var endFn = function () {
    timeout = 0
    if (!runFlag && optTrailing === true) {
      runFn()
    }
  }
  var cancelFn = function () {
    var rest = timeout !== 0
    clearTimeout(timeout)
    runFlag = false
    timeout = 0
    return rest
  }
  var throttled = function () {
    args = arguments
    context = this
    runFlag = false
    if (timeout === 0) {
      if (optLeading === true) {
        runFn()
      } else if (optTrailing === true) {
        timeout = setTimeout(endFn, wait)
      }
    }
  }
  throttled.cancel = cancelFn
  return throttled
}
254850
function hide() {
              cancelShow();
              cancelHide();

              if (!ttScope) {
                return;
              }

              // First things first: we don't show it anymore.
              ttScope.$evalAsync(function() {
                ttScope.isOpen = false;
                assignIsOpen(false);
                // And now we remove it from the DOM. However, if we have animation, we
                // need to wait for it to expire beforehand.
                // FIXME: this is a placeholder for a port of the transitions library.
                // The fade transition in TWBS is 150ms.
                if (ttScope.animation) {
                  if (!transitionTimeout) {
                    transitionTimeout = $timeout(removeTooltip, 150, false);
                  }
                } else {
                  removeTooltip();
                }
              });
            }
22104
function(startVal, endVal, drawFn, finishCallback) {
            var animationRange = endVal - startVal,
                duration = 500,
                animationProperties = {
                    duration: duration,
                    step: function(now, fx) {
                        drawFn(startVal + now);
                        this.nudgeChart();
                    }.bind(this)
                };

            if(finishCallback) {
                animationProperties.complete = function() {
                    finishCallback(endVal);
                };
            }
            // for the animation start and end values, use 0 and animationRange for consistency with the way jQuery handles
            // css properties that it doesn't recognize
            $(this.renderTo)
                .stop(true, true)
                .css({'animation-progress': 0})
                .animate({'animation-progress': animationRange}, animationProperties);
        }
820579
function animate(from, to, {duration, easingFunction, horizontal}) {
  for (const element of [from, to]) {
    element.style.pointerEvents = 'none';
  }

  if (horizontal) {
    const width = from.offsetWidth;
    from.style.transform = `translate3d(${width}px, 0, 0)`;
    to.style.transform = `translate3d(-${width}px, 0, 0)`;
  } else {
    const height = from.offsetHeight;
    from.style.transform = `translate3d(0, ${height}px, 0)`;
    to.style.transform = `translate3d(0, -${height}px, 0)`;
  }

  requestAnimationFrame(() => {
    for (const element of [from, to]) {
      element.addEventListener('transitionend', resetElementOnTransitionEnd);
      element.style.transition = `transform ${duration}ms ${easingFunction}`;
      element.style.transform = '';
    }
  });
}
293412
function stop () {
        currentValues = fromValues;
        triggerEvent('stop');
        stopLoop(animationId);
        pausedAfter = undefined;
        startTime = undefined;
        return self;
      }
1218262
function getAnimationProps(selector, opts, duration, easing, interval){
  const animationProps = []
  for(let i in opts){
    const attr = i
    const currentOriginValue = getStyle(selector, attr)
    const currentValue = parseFloat(currentOriginValue)
    const targetValue = parseFloat(opts[i])
    const unit = currentOriginValue.replace(currentValue, '')
    animationProps.push({
      attr: i,
      numbers: generateNumber(currentValue, targetValue, duration, easing, interval),
      unit: unit,
    })
  }
  return animationProps
}
1220223
function _delay(tag, ms, callback) {
		/*jshint -W040:true */
		var self = this;

		tag = "" + (tag || "default");
		if (timerMap[tag] != null) {
			clearTimeout(timerMap[tag]);
			delete timerMap[tag];
			// console.log("Cancel timer '" + tag + "'");
		}
		if (ms == null || callback == null) {
			return;
		}
		// console.log("Start timer '" + tag + "'");
		timerMap[tag] = setTimeout(function() {
			// console.log("Execute timer '" + tag + "'");
			callback.call(self);
		}, +ms);
	}
38176
function delay(ms, done) {

  // Work around IE8 bug whereby a setTimeout callback may still be called
  // after the corresponding clearTimeout is invoked.
  var timer = null;

  function finish() {
    if (timer != null) {
      timer = null;
      done(null);
    }
  }

  function cancel() {
    if (timer != null) {
      clearTimeout(timer);
      timer = null;
      done.apply(null, arguments);
    }
  }

  timer = setTimeout(finish, ms);

  return cancel;

}
750251
function (easing, forceAnimate) {

        var self = this;
        var clipCount = 0;

        var oneTrackDone = function () {
            clipCount--;
            if (!clipCount) {
                self._doneCallback();
            }
        };

        var lastClip;
        for (var propName in this._tracks) {
            if (!this._tracks.hasOwnProperty(propName)) {
                continue;
            }
            var clip = createTrackClip(
                this, easing, oneTrackDone,
                this._tracks[propName], propName, forceAnimate
            );
            if (clip) {
                this._clipList.push(clip);
                clipCount++;

                // If start after added to animation
                if (this.animation) {
                    this.animation.addClip(clip);
                }

                lastClip = clip;
            }
        }

        // Add during callback on the last clip
        if (lastClip) {
            var oldOnFrame = lastClip.onframe;
            lastClip.onframe = function (target, percent) {
                oldOnFrame(target, percent);

                for (var i = 0; i < self._onframeList.length; i++) {
                    self._onframeList[i](target, percent);
                }
            };
        }

        // This optimization will help the case that in the upper application
        // the view may be refreshed frequently, where animation will be
        // called repeatly but nothing changed.
        if (!clipCount) {
            this._doneCallback();
        }
        return this;
    }
930628
function(callbacks) {
    callbacks = callbacks || { };

    var empty = function() { },
        onComplete = callbacks.onComplete || empty,
        onChange = callbacks.onChange || empty,
        _this = this;

    fabric.util.animate({
      startValue: this.get('angle'),
      endValue: this._getAngleValueForStraighten(),
      duration: this.FX_DURATION,
      onChange: function(value) {
        _this.setAngle(value);
        onChange();
      },
      onComplete: function() {
        _this.setCoords();
        onComplete();
      },
      onStart: function() {
        _this.setActive(false);
      }
    });

    return this;
  }
242287
function(delay) {
            var view = this.currentView,
                value = this[view],
                isHours = view === 'hours',
                unit = Math.PI / (isHours ? 6 : 30),
                radian = value * unit,
                radius = isHours && value > 0 && value < 13 ? innerRadius : outerRadius,
                x = Math.sin(radian) * radius,
                y = - Math.cos(radian) * radius,
                self = this;
            
            if (svgSupported && delay) {
                self.canvas.addClass('jqclockpicker-canvas-out');
                setTimeout(function() {
                    self.canvas.removeClass('jqclockpicker-canvas-out');
                    self.setHand(x, y);
                }, delay);
            } else {
                this.setHand(x, y);
            }
        }
1168920
function(func, arr, opts) {
		var dfrd = $.Deferred(),
			abortFlg = false,
			parms = Object.assign({
				interval : 0,
				numPerOnce : 1
			}, opts || {}),
			resArr = [],
			vars =[],
			curVars = [],
			exec,
			tm;
		
		dfrd._abort = function(resolve) {
			tm && clearTimeout(tm);
			vars = [];
			abortFlg = true;
			if (dfrd.state() === 'pending') {
				dfrd[resolve? 'resolve' : 'reject'](resArr);
			}
		};
		
		dfrd.fail(function() {
			dfrd._abort();
		}).always(function() {
			dfrd._abort = function() {};
		});

		if (typeof func === 'function' && Array.isArray(arr)) {
			vars = arr.concat();
			exec = function() {
				var i, len, res;
				if (abortFlg) {
					return;
				}
				curVars = vars.splice(0, parms.numPerOnce);
				len = curVars.length;
				for (i = 0; i < len; i++) {
					if (abortFlg) {
						break;
					}
					res = func(curVars[i]);
					(res !== null) && resArr.push(res);
				}
				if (abortFlg) {
					return;
				}
				if (vars.length) {
					tm = setTimeout(exec, parms.interval);
				} else {
					dfrd.resolve(resArr);
				}
			};
			if (vars.length) {
				tm = setTimeout(exec, 0);
			} else {
				dfrd.resolve(resArr);
			}
		} else {
			dfrd.reject();
		}
		return dfrd;
	}
723739
function(animator, target, duration, easing) {
                this.callMixin();
                this.target = target;
                this.time = 0;
                this.duration = duration;
                this.easing = easing;
                this.animator = animator;
                this.beginValue = animator.beginValue;
                this.finishValue = animator.finishValue;
                this.setter = animator.setter;
                this.status = "ready";
            }
1343551
function(o) {
      var options = {};
      "duration after easing".split(' ').forEach( function(p) {
        if (props[p]) {
            options[p] = props[p];
            delete props[p];
        }
      });
      return options;
    }
648971
function parallax(scrollPosition, start, duration, startValue, endValue, easing) {
  let min = startValue;
  let max = endValue;
  const invert = startValue > endValue;


  // Safety check, if "startValue" is in the wrong format
  if (typeof startValue !== 'number') {
    console.warn(`Plx, ERROR: startValue is not a number (type: "${ typeof endValue }", value: "${ endValue }")`); // eslint-disable-line
    return null;
  }

  // Safety check, if "endValue" is in the wrong format
  if (typeof endValue !== 'number') {
    console.warn(`Plx, ERROR: endValue is not a number (type: "${ typeof endValue }", value: "${ endValue }")`); // eslint-disable-line
    return null;
  }

  // Safety check, if "duration" is in the wrong format
  if (typeof duration !== 'number' || duration === 0) {
    console.warn(`Plx, ERROR: duration is zero or not a number (type: "${ typeof duration }", value: "${ duration }")`); // eslint-disable-line
    return null;
  }

  if (invert) {
    min = endValue;
    max = startValue;
  }

  let percentage = ((scrollPosition - start) / duration);

  if (percentage > 1) {
    percentage = 1;
  } else if (percentage < 0) {
    percentage = 0;
  }

  // Apply easing
  if (easing) {
    const easingPropType = typeof easing;
    if (easingPropType === 'object' && easing.length === 4) {
      percentage = BezierEasing(
        easing[0],
        easing[1],
        easing[2],
        easing[3]
      )(percentage);
    } else if (easingPropType === 'string' && EASINGS[easing]) {
      percentage = BezierEasing(
        EASINGS[easing][0],
        EASINGS[easing][1],
        EASINGS[easing][2],
        EASINGS[easing][3]
      )(percentage);
    } else if (easingPropType === 'function') {
      percentage = easing(percentage);
    }
  }

  let value = percentage * (max - min);

  if (invert) {
    value = max - value;
  } else {
    value += min;
  }

  return parseFloat(value.toFixed(3));
}
1217801
function AnimationThrottler(delay) {
  if(!delay) delay = DELAY;

  // Anim is considered active if it's running or queued
  var currentDelay = 0;

  // func: Function that takes no params and returns a promise
  function requestAnim(func) {
    var result = q.delay(currentDelay)
      .thenResolve(func)
      .then(start);
    currentDelay += delay;
    return result;
  }
  this.requestAnim = requestAnim;

  function start(func) {
    return func()
      .catch(animFailed)
      .tap(animFinished);
  }

  function animFailed(error) {
    animFinished();
    throw error;
  }

  function animFinished() {
    currentDelay -= delay;
  }
}