| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- define(function(require, exports, module) {
- "use strict";
- var Util = require('./util');
- var Base = require('./base');
- var Easing = require('./easing');
- var RAF = window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function(callback) {
- window.setTimeout(callback, 1000 / 60);
- };
- var vendors = ['webkit', 'moz', 'ms', 'o'];
- var cancelRAF = window.cancelAnimationFrame;
- if (!cancelRAF) {
- for (var i = 0; i < vendors.length; i++) {
- if (window[vendors[i] + 'CancelAnimationFrame'] || window[vendors[i] + 'CancelRequestAnimationFrame']) {
- cancelRAF = window[vendors[i] + 'CancelAnimationFrame'] || window[vendors[i] + 'CancelRequestAnimationFrame'];
- }
- }
- }
- cancelRAF = cancelRAF || window.clearTimeout;
- function Bezier(x1, y1, x2, y2, epsilon) {
- var curveX = function(t) {
- var v = 1 - t;
- return 3 * v * v * t * x1 + 3 * v * t * t * x2 + t * t * t;
- };
- var curveY = function(t) {
- var v = 1 - t;
- return 3 * v * v * t * y1 + 3 * v * t * t * y2 + t * t * t;
- };
- var derivativeCurveX = function(t) {
- var v = 1 - t;
- return 3 * (2 * (t - 1) * t + v * v) * x1 + 3 * (-t * t * t + 2 * v * t) * x2;
- };
- return function(t) {
- var x = t,
- t0, t1, t2, x2, d2, i;
- // First try a few iterations of Newton's method -- normally very fast.
- for (t2 = x, i = 0; i < 8; i++) {
- x2 = curveX(t2) - x;
- if (Math.abs(x2) < epsilon) return curveY(t2);
- d2 = derivativeCurveX(t2);
- if (Math.abs(d2) < 1e-6) break;
- t2 = t2 - x2 / d2;
- }
- t0 = 0, t1 = 1, t2 = x;
- if (t2 < t0) return curveY(t0);
- if (t2 > t1) return curveY(t1);
- // Fallback to the bisection method for reliability.
- while (t0 < t1) {
- x2 = curveX(t2);
- if (Math.abs(x2 - x) < epsilon) return curveY(t2);
- if (x > x2) t0 = t2;
- else t1 = t2;
- t2 = (t1 - t0) * .5 + t0;
- }
- // Failure
- return curveY(t2);
- };
- };
- function Timer(cfg) {
- var self = this;
- self.cfg = Util.mix({
- easing: "linear"
- }, cfg)
- }
- Timer.MIN_DURATION = 1;
- Util.extend(Timer, Base, {
- reset: function(cfg) {
- var self = this;
- Util.mix(self.cfg, cfg);
- self.isfinished = false;
- self.percent = 0;
- self._stop = null;
- },
- run: function() {
- var self = this;
- var duration = self.cfg.duration;
- if (duration <= Timer.MIN_DURATION) {
- self.isfinished = true;
- self.trigger("run", {
- percent: 1
- });
- self.trigger("end", {
- percent: 1
- });
- }
- if (self.isfinished) return;
- self._hasFinishedPercent = self._stop && self._stop.percent || 0;
- self._stop = null;
- self.start = Date.now();
- self.percent = 0;
- // epsilon determines the precision of the solved values
- var epsilon = (1000 / 60 / duration) / 4;
- var b = Easing[self.cfg.easing];
- self.easingFn = Bezier(b[0], b[1], b[2], b[3], epsilon);
- self._run();
- },
- _run: function() {
- var self = this;
- cancelRAF(self._raf);
- self._raf = RAF(function() {
- self.now = Date.now();
- self.duration = self.now - self.start >= self.cfg.duration ? self.cfg.duration : self.now - self.start;
- self.progress = self.easingFn(self.duration / self.cfg.duration);
- self.percent = self.duration / self.cfg.duration + self._hasFinishedPercent;
- if (self.percent >= 1 || self._stop) {
- self.percent = self._stop && self._stop.percent ? self._stop.percent : 1;
- self.duration = self._stop && self._stop.duration ? self._stop.duration : self.duration;
- var param = {
- percent: self.percent
- };
- self.trigger("stop", param);
- if (self.percent >= 1) {
- self.isfinished = true;
- self.trigger("end", {
- percent: 1
- });
- }
- return;
- }
- self.trigger("run", {
- percent: self.progress,
- originPercent:self.percent
- });
- self._run();
- })
- },
- stop: function() {
- var self = this;
- self._stop = {
- percent: self.percent,
- now: self.now
- };
- cancelRAF(self._raf)
- }
- });
- if (typeof module == 'object' && module.exports) {
- module.exports = Timer;
- }
- /** ignored by jsdoc **/
- else {
- return Timer;
- }
- });
|