diff options
Diffstat (limited to 'src/utils.mjs')
-rw-r--r-- | src/utils.mjs | 56 |
1 files changed, 46 insertions, 10 deletions
diff --git a/src/utils.mjs b/src/utils.mjs index 4c58dc1..e694d4a 100644 --- a/src/utils.mjs +++ b/src/utils.mjs | |||
@@ -1,4 +1,9 @@ | |||
1 | // Disconnect MutationObserver if element is removed | 1 | /** |
2 | * Do callback when HTMLElement in removed | ||
3 | * | ||
4 | * @param {HTMLElement} element observing | ||
5 | * @param {Function} callback | ||
6 | */ | ||
2 | export const onRemove = (element, callback) => { | 7 | export const onRemove = (element, callback) => { |
3 | const parent = element.parentNode; | 8 | const parent = element.parentNode; |
4 | if (!parent) throw new Error("The node must already be attached"); | 9 | if (!parent) throw new Error("The node must already be attached"); |
@@ -16,10 +21,21 @@ export const onRemove = (element, callback) => { | |||
16 | obs.observe(parent, { childList: true, }); | 21 | obs.observe(parent, { childList: true, }); |
17 | } | 22 | } |
18 | 23 | ||
19 | // Animation for new rectangle | 24 | /** |
20 | export const animateRectTransition = (child, rect, resume = false) => { | 25 | * Animate transition of DOMRect, with Web Animation API |
26 | * | ||
27 | * @param {HTMLElement} element Element which animation applies | ||
28 | * @param {DOMRect} rect DOMRect for transition | ||
29 | * @param {Object} options | ||
30 | * @param {Boolean} options.resume If true, transition starts from rect to DOMRect of element | ||
31 | * @param {Number} options.duration Duration of animation in milliseconds | ||
32 | * @returns {Animation} https://developer.mozilla.org/en-US/docs/Web/API/Animation | ||
33 | */ | ||
34 | export const animateRectTransition = (element, rect, options = {}) => { | ||
35 | if (!element.parentElement) throw new Error("The node must already be attached"); | ||
36 | |||
21 | const { width: w1, height: h1, left: x1, top: y1 } = rect | 37 | const { width: w1, height: h1, left: x1, top: y1 } = rect |
22 | const { width: w2, height: h2, left: x2, top: y2 } = child.getBoundingClientRect() | 38 | const { width: w2, height: h2, left: x2, top: y2 } = element.getBoundingClientRect() |
23 | 39 | ||
24 | const rw = w1 / w2 | 40 | const rw = w1 / w2 |
25 | const rh = h1 / h2 | 41 | const rh = h1 / h2 |
@@ -36,13 +52,33 @@ export const animateRectTransition = (child, rect, resume = false) => { | |||
36 | { transform: transform1, opacity: 1 }, | 52 | { transform: transform1, opacity: 1 }, |
37 | { transform: transform2, opacity: 0.3 }, | 53 | { transform: transform2, opacity: 0.3 }, |
38 | ] | 54 | ] |
55 | if (options.resume === true) keyframes.reverse() | ||
39 | 56 | ||
40 | return child.animate( | 57 | return element.animate( |
41 | resume | 58 | keyframes, |
42 | ? keyframes.reverse() | ||
43 | : keyframes, | ||
44 | { | 59 | { |
45 | duration: 300, | 60 | duration: options.duration ?? 300, |
46 | easing: 'ease-in-out', | 61 | easing: 'ease-in-out', |
47 | }); | 62 | } |
63 | ); | ||
64 | } | ||
65 | |||
66 | |||
67 | /** | ||
68 | * Throttle for function call | ||
69 | * | ||
70 | * @param {Function} func | ||
71 | * @param {Number} delay milliseconds | ||
72 | * @returns {Any} return value of function call, or null if throttled | ||
73 | */ | ||
74 | export function throttle(func, delay) { | ||
75 | let timerFlag = null; | ||
76 | |||
77 | return (...args) => { | ||
78 | if (timerFlag !== null) return null | ||
79 | timerFlag = setTimeout(() => { | ||
80 | timerFlag = null; | ||
81 | }, delay); | ||
82 | return func(...args); | ||
83 | }; | ||
48 | } | 84 | } |