[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/webroot/rsrc/externals/javelin/ext/fx/ -> FX.js (source)

   1  /**
   2   * @provides javelin-fx
   3   * @requires javelin-color javelin-install javelin-util
   4   * @javelin
   5   *
   6   * Based on moo.fx (moofx.mad4milk.net).
   7   */
   8  
   9  JX.install('FX', {
  10  
  11    events: ['start', 'complete'],
  12  
  13    construct: function(element) {
  14      this._config = {};
  15      this.setElement(element);
  16      this.setTransition(JX.FX.Transitions.sine);
  17    },
  18  
  19    properties: {
  20      fps: 50,
  21      wait: true,
  22      duration: 500,
  23      element: null,
  24      property: null,
  25      transition: null
  26    },
  27  
  28    members: {
  29      _to: null,
  30      _now: null,
  31      _from: null,
  32      _start: null,
  33      _config: null,
  34      _interval: null,
  35  
  36      start: function(config) {
  37        if (__DEV__) {
  38          if (!config) {
  39            throw new Error('What styles do you want to animate?');
  40          }
  41          if (!this.getElement()) {
  42            throw new Error('What element do you want to animate?');
  43          }
  44        }
  45        if (this._interval && this.getWait()) {
  46          return;
  47        }
  48        var from = {};
  49        var to = {};
  50        for (var prop in config) {
  51          from[prop] = config[prop][0];
  52          to[prop] = config[prop][1];
  53          if (/color/i.test(prop)) {
  54            from[prop] = JX.Color.hexToRgb(from[prop], true);
  55            to[prop] = JX.Color.hexToRgb(to[prop], true);
  56          }
  57        }
  58        this._animate(from, to);
  59        return this;
  60      },
  61  
  62      stop: function() {
  63        clearInterval(this._interval);
  64        this._interval = null;
  65        return this;
  66      },
  67  
  68      then: function(func) {
  69        var token = this.listen('complete', function() {
  70          token.remove();
  71          func();
  72        });
  73        return this;
  74      },
  75  
  76      _animate: function(from, to) {
  77        if (!this.getWait()) {
  78          this.stop();
  79        }
  80        if (this._interval) {
  81          return;
  82        }
  83        setTimeout(JX.bind(this, this.invoke, 'start'), 10);
  84        this._from = from;
  85        this._to = to;
  86        this._start = JX.now();
  87        this._interval = setInterval(
  88          JX.bind(this, this._tween),
  89          Math.round(1000 / this.getFps()));
  90  
  91        // Immediately update to the initial values.
  92        this._tween();
  93      },
  94  
  95      _tween: function() {
  96        var now = JX.now();
  97        var prop;
  98        if (now < this._start + this.getDuration()) {
  99          this._now = now - this._start;
 100          for (prop in this._from) {
 101            this._config[prop] = this._compute(this._from[prop], this._to[prop]);
 102          }
 103        } else {
 104          setTimeout(JX.bind(this, this.invoke, 'complete'), 10);
 105  
 106          // Compute the final position using the transition function, in case
 107          // the function applies transformations.
 108          this._now = this.getDuration();
 109          for (prop in this._from) {
 110            this._config[prop] = this._compute(this._from[prop], this._to[prop]);
 111          }
 112          this.stop();
 113        }
 114        this._render();
 115      },
 116  
 117      _compute: function(from, to) {
 118        if (JX.isArray(from)) {
 119          return from.map(function(value, ii) {
 120            return Math.round(this._compute(value, to[ii]));
 121          }, this);
 122        }
 123        var delta = to - from;
 124        return this.getTransition()(this._now, from, delta, this.getDuration());
 125      },
 126  
 127      _render: function() {
 128        var style = this.getElement().style;
 129        for (var prop in this._config) {
 130          var value = this._config[prop];
 131          if (prop == 'opacity') {
 132            value = parseInt(100 * value, 10);
 133            if (window.ActiveXObject) {
 134              style.filter = 'alpha(opacity=' + value + ')';
 135            } else {
 136              style.opacity = value / 100;
 137            }
 138          } else if (/color/i.test(prop)) {
 139            style[prop] = 'rgb(' + value + ')';
 140          } else {
 141            style[prop] = value + 'px';
 142          }
 143        }
 144      }
 145    },
 146  
 147    statics: {
 148      fade: function(element, visible) {
 149        return new JX.FX(element).setDuration(250).start({
 150          opacity: visible ? [0, 1] : [1, 0]
 151        });
 152      },
 153  
 154      highlight: function(element, color) {
 155        color = color || '#fff8dd';
 156        return new JX.FX(element).setDuration(1000).start({
 157          backgroundColor: [color, '#fff']
 158        });
 159      },
 160  
 161      /**
 162       * Easing equations based on work by Robert Penner
 163       * http://www.robertpenner.com/easing/
 164       */
 165      Transitions: {
 166        linear: function(t, b, c, d) {
 167          return c * t / d + b;
 168        },
 169  
 170        sine: function(t, b, c, d) {
 171          return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
 172        },
 173  
 174        sineIn: function(t, b, c, d) {
 175          if (t == d) {
 176            return c + b;
 177          }
 178          return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
 179        },
 180  
 181        sineOut: function(t, b, c, d) {
 182          if (t == d) {
 183            return c + b;
 184          }
 185          return c * Math.sin(t / d * (Math.PI / 2)) + b;
 186        },
 187  
 188        elastic: function(t, b, c, d, a, p) {
 189          if (t === 0) { return b; }
 190          if ((t /= d) == 1) { return b + c; }
 191          if (!p) { p = d * 0.3; }
 192          if (!a) { a = 1; }
 193          var s;
 194          if (a < Math.abs(c)) {
 195            a = c;
 196            s = p / 4;
 197          } else {
 198            s = p / (2 * Math.PI) * Math.asin(c / a);
 199          }
 200          return a * Math.pow(2, -10 * t) *
 201            Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b;
 202        },
 203  
 204        bounce: function(t, b, c, d) {
 205          if ((t /= d) < (1 / 2.75)) {
 206            return c * (7.5625 * t * t) + b;
 207          } else if (t < (2 / 2.75)) {
 208            return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
 209          } else if (t < (2.5 / 2.75)) {
 210            return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
 211          } else {
 212            return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
 213          }
 214        }
 215      }
 216    }
 217  });


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1