-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
/
Copy pathanimations.js
93 lines (73 loc) · 1.97 KB
/
animations.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { identity as linear, noop, now } from './utils.js';
import { loop } from './loop.js';
import { create_rule, delete_rule } from './style_manager.js';
export function create_animation(node, from, fn, params) {
if (!from) return noop;
const to = node.getBoundingClientRect();
if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom) return noop;
const {
delay = 0,
duration = 300,
easing = linear,
start: start_time = now() + delay,
end = start_time + duration,
tick = noop,
css
} = fn(node, { from, to }, params);
let running = true;
let started = false;
let name;
const css_text = node.style.cssText;
function start() {
if (css) {
if (delay) node.style.cssText = css_text; // TODO create delayed animation instead?
name = create_rule(node, 0, 1, duration, 0, easing, css);
}
started = true;
}
function stop() {
if (css) delete_rule(node, name);
running = false;
}
loop(now => {
if (!started && now >= start_time) {
start();
}
if (started && now >= end) {
tick(1, 0);
stop();
}
if (!running) {
return false;
}
if (started) {
const p = now - start_time;
const t = 0 + 1 * easing(p / duration);
tick(t, 1 - t);
}
return true;
});
if (delay) {
if (css) node.style.cssText += css(0, 1);
} else {
start();
}
tick(0, 1);
return stop;
}
export function fix_position(node) {
const style = getComputedStyle(node);
if (style.position !== 'absolute' && style.position !== 'fixed') {
const { width, height } = style;
const a = node.getBoundingClientRect();
node.style.position = 'absolute';
node.style.width = width;
node.style.height = height;
const b = node.getBoundingClientRect();
if (a.left !== b.left || a.top !== b.top) {
const style = getComputedStyle(node);
const transform = style.transform === 'none' ? '' : style.transform;
node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;
}
}
}