diff options
Diffstat (limited to 'src/utils.mjs')
-rw-r--r-- | src/utils.mjs | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/src/utils.mjs b/src/utils.mjs index 3824672..d9ed2d7 100644 --- a/src/utils.mjs +++ b/src/utils.mjs | |||
@@ -5,21 +5,21 @@ | |||
5 | * @param {Function} callback | 5 | * @param {Function} callback |
6 | */ | 6 | */ |
7 | export const onRemove = (element, callback) => { | 7 | export const onRemove = (element, callback) => { |
8 | const parent = element.parentNode; | 8 | const parent = element.parentNode |
9 | if (!parent) throw new Error('The node must already be attached'); | 9 | if (!parent) throw new Error('The node must already be attached') |
10 | 10 | ||
11 | const obs = new MutationObserver(mutations => { | 11 | const obs = new window.MutationObserver(mutations => { |
12 | for (const mutation of mutations) { | 12 | for (const mutation of mutations) { |
13 | for (const el of mutation.removedNodes) { | 13 | for (const el of mutation.removedNodes) { |
14 | if (el === element) { | 14 | if (el === element) { |
15 | obs.disconnect(); | 15 | obs.disconnect() |
16 | callback(); | 16 | callback() |
17 | } | 17 | } |
18 | } | 18 | } |
19 | } | 19 | } |
20 | }); | 20 | }) |
21 | obs.observe(parent, { childList: true }); | 21 | obs.observe(parent, { childList: true }) |
22 | }; | 22 | } |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * Animate transition of DOMRect, with Web Animation API | 25 | * Animate transition of DOMRect, with Web Animation API |
@@ -32,39 +32,38 @@ export const onRemove = (element, callback) => { | |||
32 | * @returns {Animation} https://developer.mozilla.org/en-US/docs/Web/API/Animation | 32 | * @returns {Animation} https://developer.mozilla.org/en-US/docs/Web/API/Animation |
33 | */ | 33 | */ |
34 | export const animateRectTransition = (element, rect, options = {}) => { | 34 | export const animateRectTransition = (element, rect, options = {}) => { |
35 | if (!element.parentElement) | 35 | if (!element.parentElement) { throw new Error('The node must already be attached') } |
36 | throw new Error('The node must already be attached'); | ||
37 | 36 | ||
38 | const { width: w1, height: h1, left: x1, top: y1 } = rect; | 37 | const { width: w1, height: h1, left: x1, top: y1 } = rect |
39 | const { | 38 | const { |
40 | width: w2, | 39 | width: w2, |
41 | height: h2, | 40 | height: h2, |
42 | left: x2, | 41 | left: x2, |
43 | top: y2, | 42 | top: y2 |
44 | } = element.getBoundingClientRect(); | 43 | } = element.getBoundingClientRect() |
45 | 44 | ||
46 | const rw = (w1 ?? w2) / w2; | 45 | const rw = (w1 ?? w2) / w2 |
47 | const rh = (h1 ?? h2) / h2; | 46 | const rh = (h1 ?? h2) / h2 |
48 | const dx = x1 - x2; | 47 | const dx = x1 - x2 |
49 | const dy = y1 - y2; | 48 | const dy = y1 - y2 |
50 | 49 | ||
51 | if ((dx === 0 && dy === 0) || !isFinite(rw) || !isFinite(rh)) { | 50 | if ((dx === 0 && dy === 0) || !isFinite(rw) || !isFinite(rh)) { |
52 | return element.animate([], { duration: 0 }); | 51 | return element.animate([], { duration: 0 }) |
53 | } | 52 | } |
54 | 53 | ||
55 | const transform1 = `translate(0, 0) scale(1, 1)`; | 54 | const transform1 = 'translate(0, 0) scale(1, 1)' |
56 | const transform2 = `translate(${dx}px, ${dy}px) scale(${rw}, ${rh})`; | 55 | const transform2 = `translate(${dx}px, ${dy}px) scale(${rw}, ${rh})` |
57 | const keyframes = [ | 56 | const keyframes = [ |
58 | { transform: transform1, opacity: 1 }, | 57 | { transform: transform1, opacity: 1 }, |
59 | { transform: transform2, opacity: 0.3 }, | 58 | { transform: transform2, opacity: 0.3 } |
60 | ]; | 59 | ] |
61 | if (options.resume === true) keyframes.reverse(); | 60 | if (options.resume === true) keyframes.reverse() |
62 | 61 | ||
63 | return element.animate(keyframes, { | 62 | return element.animate(keyframes, { |
64 | duration: options.duration ?? 500, | 63 | duration: options.duration ?? 500, |
65 | easing: 'ease-in-out', | 64 | easing: 'ease-in-out' |
66 | }); | 65 | }) |
67 | }; | 66 | } |
68 | 67 | ||
69 | /** | 68 | /** |
70 | * Throttle for function call | 69 | * Throttle for function call |
@@ -73,18 +72,18 @@ export const animateRectTransition = (element, rect, options = {}) => { | |||
73 | * @param {Number} delay milliseconds | 72 | * @param {Number} delay milliseconds |
74 | * @returns {Any} return value of function call, or null if throttled | 73 | * @returns {Any} return value of function call, or null if throttled |
75 | */ | 74 | */ |
76 | export function throttle(func, delay) { | 75 | export function throttle (func, delay) { |
77 | let timerFlag = null; | 76 | let timerFlag = null |
78 | 77 | ||
79 | return function (...args) { | 78 | return function (...args) { |
80 | const context = this; | 79 | const context = this |
81 | if (timerFlag !== null) return null; | 80 | if (timerFlag !== null) return null |
82 | 81 | ||
83 | timerFlag = setTimeout( | 82 | timerFlag = setTimeout( |
84 | () => (timerFlag = null), | 83 | () => (timerFlag = null), |
85 | typeof delay === 'function' ? delay.call(context) : delay, | 84 | typeof delay === 'function' ? delay.call(context) : delay |
86 | ); | 85 | ) |
87 | 86 | ||
88 | return func.call(context, ...args); | 87 | return func.call(context, ...args) |
89 | }; | 88 | } |
90 | } | 89 | } |