From 7627d3970070bddc41d8898277517ad66521475c Mon Sep 17 00:00:00 2001 From: mourner Date: Fri, 10 Aug 2012 21:50:00 +0300 Subject: [PATCH] improve PosAnimation code a bit --- src/dom/PosAnimation.Timer.js | 26 ++++++++++++++++---------- src/dom/PosAnimation.js | 23 ++++++++++++++++------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/dom/PosAnimation.Timer.js b/src/dom/PosAnimation.Timer.js index e2edcc24..5187bc40 100644 --- a/src/dom/PosAnimation.Timer.js +++ b/src/dom/PosAnimation.Timer.js @@ -1,17 +1,17 @@ /* * L.PosAnimation fallback implementation that powers Leaflet pan animations - * in browsers that don't support CSS3 Transitions + * in browsers that don't support CSS3 Transitions. */ -L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.Class.extend({ - includes: L.Mixin.Events, +L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.PosAnimation.extend({ - run: function (el, newPos, duration) { + run: function (el, newPos, duration, easing) { // (HTMLElement, Point[, Number, String]) this.stop(); this._el = el; this._inProgress = true; - this._duration = duration; + this._duration = duration || 0.25; + this._ease = this._easings[easing || 'ease-out']; this._startPos = L.DomUtil.getPosition(el); this._offset = newPos.subtract(this._startPos); @@ -30,7 +30,8 @@ L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.Class.extend({ }, _animate: function () { - this._animId = L.Util.requestAnimFrame(this._animate, this, false, this._el); + // animation loop + this._animId = L.Util.requestAnimFrame(this._animate, this); this._step(); }, @@ -39,7 +40,7 @@ L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.Class.extend({ duration = this._duration * 1000; if (elapsed < duration) { - this._runFrame(this._easeOut(elapsed / duration)); + this._runFrame(this._ease(elapsed / duration)); } else { this._runFrame(1); this._complete(); @@ -49,16 +50,21 @@ L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.Class.extend({ _runFrame: function (progress) { var pos = this._startPos.add(this._offset.multiplyBy(progress)); L.DomUtil.setPosition(this._el, pos); + this.fire('step'); }, _complete: function () { L.Util.cancelAnimFrame(this._animId); - this.fire('end'); + this._inProgress = false; + this.fire('end'); }, - _easeOut: function (t) { - return t * (2 - t); + // easing functions, they map time progress to movement progress + _easings: { + 'ease-out': function (t) { return t * (2 - t); }, + 'linear': function (t) { return t; } } + }); diff --git a/src/dom/PosAnimation.js b/src/dom/PosAnimation.js index de3c88e2..cdc20c35 100644 --- a/src/dom/PosAnimation.js +++ b/src/dom/PosAnimation.js @@ -1,11 +1,11 @@ /* - * L.PosAnimation is used by Leaflet internally for pan animations + * L.PosAnimation is used by Leaflet internally for pan animations. */ L.PosAnimation = L.Class.extend({ includes: L.Mixin.Events, - run: function (el, newPos, duration) { + run: function (el, newPos, duration, easing) { // (HTMLElement, Point[, Number, String]) this.stop(); this._el = el; @@ -13,24 +13,31 @@ L.PosAnimation = L.Class.extend({ this.fire('start'); - el.style[L.DomUtil.TRANSITION] = 'all ' + duration + 's ease-out'; + el.style[L.DomUtil.TRANSITION] = 'all ' + (duration || 0.25) + 's ' + (easing || 'ease-out'); L.DomEvent.on(el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this); L.DomUtil.setPosition(el, newPos); - // Chrome flickers for some reason if you don't do this + // toggle reflow, Chrome flickers for some reason if you don't do this L.Util.falseFn(el.offsetWidth); + + // there's no native way to track value updates of tranisitioned properties, so we imitate this + this._stepTimer = setInterval(L.Util.bind(this.fire, this, 'step'), 50); }, stop: function () { if (!this._inProgress) { return; } - var pos = this._getPos(); + // if we just removed the transition property, the element would jump to its final position, + // so we need to make it stay at the current position - L.DomUtil.setPosition(this._el, pos); + L.DomUtil.setPosition(this._el, this._getPos()); this._onTransitionEnd(); }, + // you can't easily get intermediate values of properties animated with CSS3 Transitions, + // we need to parse computed style (in case of transform it returns matrix string) + _transformRe: /(-?[\d\.]+), (-?[\d\.]+)\)/, _getPos: function () { @@ -58,7 +65,9 @@ L.PosAnimation = L.Class.extend({ this._el.style[L.DomUtil.TRANSITION] = ''; - this.fire('end'); + clearInterval(this._stepTimer); + + this.fire('step').fire('end'); } });