UNPKG

2.44 kBJavaScriptView Raw
1import * as Util from '../core/Util';
2import {Evented} from '../core/Events';
3import * as DomUtil from '../dom/DomUtil';
4
5
6/*
7 * @class PosAnimation
8 * @aka L.PosAnimation
9 * @inherits Evented
10 * Used internally for panning animations, utilizing CSS3 Transitions for modern browsers and a timer fallback for IE6-9.
11 *
12 * @example
13 * ```js
14 * var fx = new L.PosAnimation();
15 * fx.run(el, [300, 500], 0.5);
16 * ```
17 *
18 * @constructor L.PosAnimation()
19 * Creates a `PosAnimation` object.
20 *
21 */
22
23export var PosAnimation = Evented.extend({
24
25 // @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number)
26 // Run an animation of a given element to a new position, optionally setting
27 // duration in seconds (`0.25` by default) and easing linearity factor (3rd
28 // argument of the [cubic bezier curve](http://cubic-bezier.com/#0,0,.5,1),
29 // `0.5` by default).
30 run: function (el, newPos, duration, easeLinearity) {
31 this.stop();
32
33 this._el = el;
34 this._inProgress = true;
35 this._duration = duration || 0.25;
36 this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2);
37
38 this._startPos = DomUtil.getPosition(el);
39 this._offset = newPos.subtract(this._startPos);
40 this._startTime = +new Date();
41
42 // @event start: Event
43 // Fired when the animation starts
44 this.fire('start');
45
46 this._animate();
47 },
48
49 // @method stop()
50 // Stops the animation (if currently running).
51 stop: function () {
52 if (!this._inProgress) { return; }
53
54 this._step(true);
55 this._complete();
56 },
57
58 _animate: function () {
59 // animation loop
60 this._animId = Util.requestAnimFrame(this._animate, this);
61 this._step();
62 },
63
64 _step: function (round) {
65 var elapsed = (+new Date()) - this._startTime,
66 duration = this._duration * 1000;
67
68 if (elapsed < duration) {
69 this._runFrame(this._easeOut(elapsed / duration), round);
70 } else {
71 this._runFrame(1);
72 this._complete();
73 }
74 },
75
76 _runFrame: function (progress, round) {
77 var pos = this._startPos.add(this._offset.multiplyBy(progress));
78 if (round) {
79 pos._round();
80 }
81 DomUtil.setPosition(this._el, pos);
82
83 // @event step: Event
84 // Fired continuously during the animation.
85 this.fire('step');
86 },
87
88 _complete: function () {
89 Util.cancelAnimFrame(this._animId);
90
91 this._inProgress = false;
92 // @event end: Event
93 // Fired when the animation ends.
94 this.fire('end');
95 },
96
97 _easeOut: function (t) {
98 return 1 - Math.pow(1 - t, this._easeOutPower);
99 }
100});