aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils.mjs
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.mjs')
-rw-r--r--src/utils.mjs67
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 */
7export const onRemove = (element, callback) => { 7export 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 */
34export const animateRectTransition = (element, rect, options = {}) => { 34export 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 */
76export function throttle(func, delay) { 75export 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}