UNPKG

leaflet

Version:

JavaScript library for mobile-friendly interactive maps

95 lines (69 loc) 2.69 kB
/* * L.PosAnimation is used by Leaflet internally for pan animations. */ L.PosAnimation = L.Class.extend({ includes: L.Mixin.Events, run: function (el, newPos, duration, easeLinearity) { // (HTMLElement, Point[, Number, Number]) this.stop(); this._el = el; this._inProgress = true; this._newPos = newPos; this.fire('start'); el.style[L.DomUtil.TRANSITION] = 'all ' + (duration || 0.25) + 's cubic-bezier(0,0,' + (easeLinearity || 0.5) + ',1)'; L.DomEvent.on(el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this); L.DomUtil.setPosition(el, newPos); // 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 transitioned properties, so we imitate this this._stepTimer = setInterval(L.bind(this._onStep, this), 50); }, stop: function () { if (!this._inProgress) { return; } // 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, this._getPos()); this._onTransitionEnd(); L.Util.falseFn(this._el.offsetWidth); // force reflow in case we are about to start a new animation }, _onStep: function () { var stepPos = this._getPos(); if (!stepPos) { this._onTransitionEnd(); return; } // jshint camelcase: false // make L.DomUtil.getPosition return intermediate position value during animation this._el._leaflet_pos = stepPos; this.fire('step'); }, // 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+)\D*, ([-+]?(?:\d*\.)?\d+)\D*\)/, _getPos: function () { var left, top, matches, el = this._el, style = window.getComputedStyle(el); if (L.Browser.any3d) { matches = style[L.DomUtil.TRANSFORM].match(this._transformRe); if (!matches) { return; } left = parseFloat(matches[1]); top = parseFloat(matches[2]); } else { left = parseFloat(style.left); top = parseFloat(style.top); } return new L.Point(left, top, true); }, _onTransitionEnd: function () { L.DomEvent.off(this._el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this); if (!this._inProgress) { return; } this._inProgress = false; this._el.style[L.DomUtil.TRANSITION] = ''; // jshint camelcase: false // make sure L.DomUtil.getPosition returns the final position value after animation this._el._leaflet_pos = this._newPos; clearInterval(this._stepTimer); this.fire('step').fire('end'); } });