diff options
Diffstat (limited to 'src/fx.js')
-rw-r--r-- | src/fx.js | 228 |
1 files changed, 105 insertions, 123 deletions
@@ -1,15 +1,13 @@ - -SVG.FX = function FX(e) { - // store target element - this.target = e; +SVG.FX = function FX(element) { + /* store target element */ + this.target = element; }; -// add FX methods +// SVG.extend(SVG.FX, { - - // animation parameters and animate + // Add animation parameters and start animation animate: function(duration, ease) { - // ensure default duration adn easing + /* ensure default duration and easing */ duration = duration || 1000; ease = ease || '<>'; @@ -19,29 +17,29 @@ SVG.extend(SVG.FX, { start = (new Date).getTime(), finish = start + duration; - // start animation + /* start animation */ this.interval = setInterval(function(){ - var i, + var index, time = (new Date).getTime(), pos = time > finish ? 1 : (time - start) / duration; - // collect attribute keys + /* collect attribute keys */ if (akeys == null) { akeys = []; - for (var k in fx.attrs) - akeys.push(k); + for (var key in fx.attrs) + akeys.push(key); }; - // collect transformation keys + /* collect transformation keys */ if (tkeys == null) { tkeys = []; - for (var k in fx.trans) - tkeys.push(k); + for (var key in fx.trans) + tkeys.push(key); tvalues = {}; }; - // apply easing + /* apply easing */ pos = ease == '<>' ? (-Math.cos(pos * Math.PI) / 2) + 0.5 : ease == '>' ? @@ -54,101 +52,101 @@ SVG.extend(SVG.FX, { ease(pos) : pos; - // run all position properties + /* run all position properties */ if (fx._move) element.move(fx._at(fx._move.x, pos), fx._at(fx._move.y, pos)); else if (fx._center) element.move(fx._at(fx._center.x, pos), fx._at(fx._center.y, pos)); - // run all size properties + /* run all size properties */ if (fx._size) element.size(fx._at(fx._size.width, pos), fx._at(fx._size.height, pos)); - // animate attributes - for (i = akeys.length - 1; i >= 0; i--) - element.attr(akeys[i], fx._at(fx.attrs[akeys[i]], pos)); + /* animate attributes */ + for (index = akeys.length - 1; index >= 0; index--) + element.attr(akeys[index], fx._at(fx.attrs[akeys[index]], pos)); - // animate transformations + /* animate transformations */ if (tkeys.length > 0) { - for (i = tkeys.length - 1; i >= 0; i--) - tvalues[tkeys[i]] = fx._at(fx.trans[tkeys[i]], pos); + for (index = tkeys.length - 1; index >= 0; index--) + tvalues[tkeys[index]] = fx._at(fx.trans[tkeys[index]], pos); element.transform(tvalues); } - // finish off animation + /* finish off animation */ if (time > finish) { clearInterval(fx.interval); - fx._after ? fx._after.apply(element) : fx.stop(); + fx._after ? fx._after.apply(element, [fx]) : fx.stop(); } }, 10); return this; }, - - // animated attributes + // Add animatable attributes attr: function(a, v, n) { if (typeof a == 'object') - for (var k in a) - this.attr(k, a[k]); + for (var key in a) + this.attr(key, a[key]); else this.attrs[a] = { from: this.target.attr(a), to: v }; return this; }, - - // animated transformations + // Add animatable transformations transform: function(o) { - for (var k in o) - this.trans[k] = { from: this.target.trans[k], to: o[k] }; + for (var key in o) + this.trans[key] = { from: this.target.trans[key], to: o[key] }; return this; }, - - // animated move + // Add animatable move move: function(x, y) { - var b = this.target.bbox(); + var box = this.target.bbox(); this._move = { - x: { from: b.x, to: x }, - y: { from: b.y, to: y } + x: { from: box.x, to: x }, + y: { from: box.y, to: y } }; return this; }, - - // animated size - size: function(w, h) { - var b = this.target.bbox(); + // Add animatable size + size: function(width, height) { + var box = this.target.bbox(); this._size = { - width: { from: b.width, to: w }, - height: { from: b.height, to: h } + width: { from: box.width, to: width }, + height: { from: box.height, to: height } }; return this; }, - - // animated center + // Add animatable center center: function(x, y) { - var b = this.target.bbox(); + var box = this.target.bbox(); this._move = { - x: { from: b.cx, to: x }, - y: { from: b.cy, to: y } + x: { from: box.cx, to: x }, + y: { from: box.cy, to: y } }; return this; }, - - // stop animation + // Callback after animation + after: function(after) { + this._after = after; + + return this; + }, + // Stop running animation stop: function() { - // stop current animation + /* stop current animation */ clearInterval(this.interval); - // create / reset storage for properties that need animation + /* reset storage for properties that need animation */ this.attrs = {}; this.trans = {}; this._move = null; @@ -157,96 +155,75 @@ SVG.extend(SVG.FX, { return this; }, - - // private: at position according to from and to - _at: function(o, p) { - // if a number, calculate pos + // Private: at position according to from and to + _at: function(o, pos) { + /* if a number, recalculate pos */ return typeof o.from == 'number' ? - o.from + (o.to - o.from) * p : + o.from + (o.to - o.from) * pos : - // if animating to a color + /* if animating to a color */ o.to.r || /^#/.test(o.to) ? - this._color(o, p) : + this._color(o, pos) : - // for all other values wait until pos has reached 1 to return the final value - p < 1 ? o.from : o.to; + /* for all other values wait until pos has reached 1 to return the final value */ + pos < 1 ? o.from : o.to; }, - - // private: tween color - _color: function(o, p) { - var f, t; + // Private: tween color + _color: function(o, pos) { + var from, to; - // convert FROM hex to rgb - f = this._h2r(o.from || '#000'); + /* convert FROM hex to rgb */ + from = this._h2r(o.from || '#000'); - // convert TO hex to rgb - t = this._h2r(o.to); + /* convert TO hex to rgb */ + to = this._h2r(o.to); - // tween color and return hex + /* tween color and return hex */ return this._r2h({ - r: ~~(f.r + (t.r - f.r) * p), - g: ~~(f.g + (t.g - f.g) * p), - b: ~~(f.b + (t.b - f.b) * p) + r: ~~(from.r + (to.r - from.r) * pos), + g: ~~(from.g + (to.g - from.g) * pos), + b: ~~(from.b + (to.b - from.b) * pos) }); }, - - // private: convert hex to rgb object - _h2r: function(h) { - // parse full hex - var m = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(this._fh(h)); - - // if the hex is successfully parsed, return it in rgb, otherwise return black - return m ? { - r: parseInt(m[1], 16), - g: parseInt(m[2], 16), - b: parseInt(m[3], 16) + // Private: convert hex to rgb object + _h2r: function(hex) { + /* parse full hex */ + var match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(this._fh(hex)); + + /* if the hex is successfully parsed, return it in rgb, otherwise return black */ + return match ? { + r: parseInt(match[1], 16), + g: parseInt(match[2], 16), + b: parseInt(match[3], 16) } : { r: 0, g: 0, b: 0 }; }, - - // private: convert rgb object to hex string - _r2h: function(r) { - return '#' + this._c2h(r.r) + this._c2h(r.g) + this._c2h(r.b); + // Private: convert rgb object to hex string + _r2h: function(rgb) { + return '#' + this._c2h(rgb.r) + this._c2h(rgb.g) + this._c2h(rgb.b); }, - - // private: convert component to hex + // Private: convert component to hex _c2h: function(c) { - var h = c.toString(16); - return h.length == 1 ? '0' + h : h; + var hex = c.toString(16); + return hex.length == 1 ? '0' + hex : hex; }, - - // private: force potential 3-based hex to 6-based - _fh: function(h) { - return h.length == 4 ? + // Private: force potential 3-based hex to 6-based + _fh: function(hex) { + return hex.length == 4 ? [ '#', - h.substring(1, 2), h.substring(1, 2), - h.substring(2, 3), h.substring(2, 3), - h.substring(3, 4), h.substring(3, 4) - ].join('') : h; + hex.substring(1, 2), hex.substring(1, 2), + hex.substring(2, 3), hex.substring(2, 3), + hex.substring(3, 4), hex.substring(3, 4) + ].join('') : hex; } }); - - -// delay: delay animation for a given amount of ms -// after: callback for when animation has finished -['delay', 'after'].forEach(function(m) { - SVG.FX.prototype[m] = function(v) { - this['_' + m] = v; - - return this; - }; -}); - - -// make SVG.Element FX-aware +// SVG.extend(SVG.Element, { - - // get fx module or create a new one, then animate with given ms and ease - animate: function(d, e) { - return (this._fx || (this._fx = new SVG.FX(this))).stop().animate(d, e); + // Get fx module or create a new one, then animate with given duration and ease + animate: function(duration, ease) { + return (this._fx || (this._fx = new SVG.FX(this))).stop().animate(duration, ease); }, - - // stop current animation + // Stop current animation; this is an alias to the fx instance stop: function() { this._fx.stop(); @@ -254,4 +231,9 @@ SVG.extend(SVG.Element, { } }); +// Usage: + +// rect.animate(1500, '>').move(200, 300).after(function() { +// this.fill({ color: '#f06' }); +// }); |