loleaflet/build/deps.js | 6 + loleaflet/src/dom/PosAnimation.Timer.js | 67 ++++++++++++++++++++ loleaflet/src/dom/PosAnimation.js | 103 +++++++++++++++++++------------ loleaflet/src/layer/AnnotationManager.js | 7 +- 4 files changed, 142 insertions(+), 41 deletions(-)
New commits: commit b0c889f2d22c05bcde392a6f2897be6465e0a3aa Author: Henry Castro <[email protected]> Date: Wed Apr 12 17:19:17 2017 -0400 loleaflet: animate the new position of selected annotation Change-Id: I47af4ac3ec01b03797a03dfcc91ec84f0fd39bb5 diff --git a/loleaflet/src/layer/AnnotationManager.js b/loleaflet/src/layer/AnnotationManager.js index 5178c921..8f66ee63 100644 --- a/loleaflet/src/layer/AnnotationManager.js +++ b/loleaflet/src/layer/AnnotationManager.js @@ -13,6 +13,7 @@ L.AnnotationManager = L.Class.extend({ this._map = map; this._items = []; this._selected = null; + this._animation = new L.PosAnimation(); this._arrow = L.polyline([], {color: 'darkblue', weight: 1}); this._map.on('AnnotationCancel', this._onAnnotationCancel, this); this._map.on('AnnotationClick', this._onAnnotationClick, this); @@ -196,10 +197,12 @@ L.AnnotationManager = L.Class.extend({ layout: function () { var docRight = this._map.project(this._map.options.maxBounds.getNorthEast()); var topRight = docRight.add(L.point(this.options.marginX, this.options.marginY)); - var annotation, selectIndex, layoutBounds, point, index; + var latlng, annotation, selectIndex, layoutBounds, point, index; if (this._selected) { selectIndex = this.getIndexOf(this._selected._data.id); - this._selected.setLatLng(this._map.unproject(L.point(docRight.x, this._selected._data.anchorPix.y))); + latlng = this._map.unproject(L.point(docRight.x, this._selected._data.anchorPix.y)); + this._animation.run(this._selected._container, this._map.latLngToLayerPoint(latlng)); + this._selected.setLatLng(latlng); layoutBounds = this._selected.getBounds(); layoutBounds.min = layoutBounds.min.add([this.options.marginX, 0]); layoutBounds.max = layoutBounds.max.add([this.options.marginX, 0]); commit 44482615ca3d355d8637ad6c04082fd1f144e10d Author: Henry Castro <[email protected]> Date: Wed Apr 12 17:17:50 2017 -0400 loleaflet: update PosAnimation.js file Change-Id: I38a2643e67d1d341b486c987eb73dc5e5608a7cb diff --git a/loleaflet/build/deps.js b/loleaflet/build/deps.js index 6cce0922..34575612 100644 --- a/loleaflet/build/deps.js +++ b/loleaflet/build/deps.js @@ -415,6 +415,12 @@ var deps = { desc: 'Core panning animation support.' }, + AnimationTimer: { + src: ['dom/PosAnimation.Timer.js'], + deps: ['AnimationPan'], + desc: 'Timer-based pan animation fallback for browsers that don\'t support CSS3 transitions.' + }, + AnimationZoom: { src: [ 'map/anim/Map.ZoomAnimation.js', diff --git a/loleaflet/src/dom/PosAnimation.Timer.js b/loleaflet/src/dom/PosAnimation.Timer.js new file mode 100644 index 00000000..52faf981 --- /dev/null +++ b/loleaflet/src/dom/PosAnimation.Timer.js @@ -0,0 +1,67 @@ +/* + * L.PosAnimation fallback implementation that powers Leaflet pan animations + * in browsers that don't support CSS3 Transitions. + */ + +L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.PosAnimation.extend({ + + run: function (el, newPos, duration, easeLinearity) { // (HTMLElement, Point[, Number, Number]) + this.stop(); + + this._el = el; + this._inProgress = true; + this._duration = duration || 0.25; + this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2); + + this._startPos = L.DomUtil.getPosition(el); + this._offset = newPos.subtract(this._startPos); + this._startTime = +new Date(); + + this.fire('start'); + + this._animate(); + }, + + stop: function () { + if (!this._inProgress) { return; } + + this._step(); + this._complete(); + }, + + _animate: function () { + // animation loop + this._animId = L.Util.requestAnimFrame(this._animate, this); + this._step(); + }, + + _step: function () { + var elapsed = (+new Date()) - this._startTime, + duration = this._duration * 1000; + + if (elapsed < duration) { + this._runFrame(this._easeOut(elapsed / duration)); + } else { + this._runFrame(1); + this._complete(); + } + }, + + _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._inProgress = false; + this.fire('end'); + }, + + _easeOut: function (t) { + return 1 - Math.pow(1 - t, this._easeOutPower); + } +}); diff --git a/loleaflet/src/dom/PosAnimation.js b/loleaflet/src/dom/PosAnimation.js index 1c8b7c07..5a2ef634 100644 --- a/loleaflet/src/dom/PosAnimation.js +++ b/loleaflet/src/dom/PosAnimation.js @@ -1,71 +1,96 @@ /* - * L.PosAnimation powers Leaflet pan animations internally. + * L.PosAnimation is used by Leaflet internally for pan animations. */ -L.PosAnimation = L.Evented.extend({ +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._duration = duration || 0.25; - // workaround for Leaflet issue #3320 - this._duration = 0; - this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2); - - this._startPos = L.DomUtil.getPosition(el); - this._offset = newPos.subtract(this._startPos); - this._startTime = +new Date(); + this._newPos = newPos; this.fire('start'); - this._animate(); + 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; } - this._step(true); - this._complete(); - }, + // 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 - _animate: function () { - // animation loop - this._animId = L.Util.requestAnimFrame(this._animate, this); - this._step(); + 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 }, - _step: function (round) { - var elapsed = (+new Date()) - this._startTime, - duration = this._duration * 1000; - - if (elapsed < duration) { - this._runFrame(this._easeOut(elapsed / duration), round); - } else { - this._runFrame(1); - this._complete(); + _onStep: function () { + var stepPos = this._getPos(); + if (!stepPos) { + this._onTransitionEnd(); + return; } + /*eslint-disable camelcase*/ + // make L.DomUtil.getPosition return intermediate position value during animation + this._el._leaflet_pos = stepPos; + /*eslint-enable camelcase*/ + + this.fire('step'); }, - _runFrame: function (progress, round) { - var pos = this._startPos.add(this._offset.multiplyBy(progress)); - if (round) { - pos._round(); + // 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); } - L.DomUtil.setPosition(this._el, pos); - this.fire('step'); + return new L.Point(left, top, true); }, - _complete: function () { - L.Util.cancelAnimFrame(this._animId); + _onTransitionEnd: function () { + L.DomEvent.off(this._el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this); + if (!this._inProgress) { return; } this._inProgress = false; - this.fire('end'); - }, - _easeOut: function (t) { - return 1 - Math.pow(1 - t, this._easeOutPower); + this._el.style[L.DomUtil.TRANSITION] = ''; + + /*eslint-disable camelcase*/ + // make sure L.DomUtil.getPosition returns the final position value after animation + this._el._leaflet_pos = this._newPos; + /*eslint-enable camelcase*/ + + clearInterval(this._stepTimer); + + this.fire('step').fire('end'); } + }); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
