diff options
| author | Hsieh Chin Fan <pham@topo.tw> | 2024-09-20 00:51:30 +0800 |
|---|---|---|
| committer | Hsieh Chin Fan <pham@topo.tw> | 2024-09-20 01:03:15 +0800 |
| commit | 7d71b5ed922c5f8472c63a6eaa3fb07f351f1c65 (patch) | |
| tree | 6d65d13e471163e7d77190ae35f70a1911c409db /src | |
| parent | 316374b44a6b613dadf32211b0cd918910af735b (diff) | |
refactor: move utils method to new module
Diffstat (limited to 'src')
| -rw-r--r-- | src/dumbymap.mjs | 46 | ||||
| -rw-r--r-- | src/utils.mjs | 48 |
2 files changed, 49 insertions, 45 deletions
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index cfaf429..4ffe58e 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs | |||
| @@ -6,53 +6,9 @@ import MarkdownItTocDoneRight from 'markdown-it-toc-done-right' | |||
| 6 | import LeaderLine from 'leader-line' | 6 | import LeaderLine from 'leader-line' |
| 7 | import PlainDraggable from 'plain-draggable' | 7 | import PlainDraggable from 'plain-draggable' |
| 8 | import { renderWith, parseConfigsFromYaml } from 'mapclay' | 8 | import { renderWith, parseConfigsFromYaml } from 'mapclay' |
| 9 | import { onRemove, animateRectTransition } from './utils' | ||
| 9 | 10 | ||
| 10 | // Utils {{{ | 11 | // Utils {{{ |
| 11 | const onRemove = (element, callback) => { | ||
| 12 | const parent = element.parentNode; | ||
| 13 | if (!parent) throw new Error("The node must already be attached"); | ||
| 14 | |||
| 15 | const obs = new MutationObserver(mutations => { | ||
| 16 | for (const mutation of mutations) { | ||
| 17 | for (const el of mutation.removedNodes) { | ||
| 18 | if (el === element) { | ||
| 19 | obs.disconnect(); | ||
| 20 | callback(); | ||
| 21 | } | ||
| 22 | } | ||
| 23 | } | ||
| 24 | }); | ||
| 25 | obs.observe(parent, { childList: true, }); | ||
| 26 | } | ||
| 27 | const animateRectTransition = (child, rect, resume = false) => { | ||
| 28 | const { width: w1, height: h1, left: x1, top: y1 } = rect | ||
| 29 | const { width: w2, height: h2, left: x2, top: y2 } = child.getBoundingClientRect() | ||
| 30 | |||
| 31 | const rw = w1 / w2 | ||
| 32 | const rh = h1 / h2 | ||
| 33 | const dx = x1 - x2; | ||
| 34 | const dy = y1 - y2; | ||
| 35 | |||
| 36 | if (dx === 0 && dy === 0) { | ||
| 37 | return; | ||
| 38 | } | ||
| 39 | |||
| 40 | const transform1 = `translate(0, 0) scale(1, 1)`; | ||
| 41 | const transform2 = `translate(${dx}px, ${dy}px) scale(${rw}, ${rh})`; | ||
| 42 | const keyframes = [ | ||
| 43 | { transform: transform1, opacity: 1 }, | ||
| 44 | { transform: transform2, opacity: 0.3 }, | ||
| 45 | ] | ||
| 46 | |||
| 47 | return child.animate( | ||
| 48 | resume | ||
| 49 | ? keyframes.reverse() | ||
| 50 | : keyframes, | ||
| 51 | { | ||
| 52 | duration: 300, | ||
| 53 | easing: 'ease-in-out', | ||
| 54 | }); | ||
| 55 | } | ||
| 56 | // }}} | 12 | // }}} |
| 57 | // FUNCTION: Get DocLinks from special anchor element {{{ | 13 | // FUNCTION: Get DocLinks from special anchor element {{{ |
| 58 | 14 | ||
diff --git a/src/utils.mjs b/src/utils.mjs new file mode 100644 index 0000000..4c58dc1 --- /dev/null +++ b/src/utils.mjs | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | // Disconnect MutationObserver if element is removed | ||
| 2 | export const onRemove = (element, callback) => { | ||
| 3 | const parent = element.parentNode; | ||
| 4 | if (!parent) throw new Error("The node must already be attached"); | ||
| 5 | |||
| 6 | const obs = new MutationObserver(mutations => { | ||
| 7 | for (const mutation of mutations) { | ||
| 8 | for (const el of mutation.removedNodes) { | ||
| 9 | if (el === element) { | ||
| 10 | obs.disconnect(); | ||
| 11 | callback(); | ||
| 12 | } | ||
| 13 | } | ||
| 14 | } | ||
| 15 | }); | ||
| 16 | obs.observe(parent, { childList: true, }); | ||
| 17 | } | ||
| 18 | |||
| 19 | // Animation for new rectangle | ||
| 20 | export const animateRectTransition = (child, rect, resume = false) => { | ||
| 21 | const { width: w1, height: h1, left: x1, top: y1 } = rect | ||
| 22 | const { width: w2, height: h2, left: x2, top: y2 } = child.getBoundingClientRect() | ||
| 23 | |||
| 24 | const rw = w1 / w2 | ||
| 25 | const rh = h1 / h2 | ||
| 26 | const dx = x1 - x2; | ||
| 27 | const dy = y1 - y2; | ||
| 28 | |||
| 29 | if (dx === 0 && dy === 0) { | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | |||
| 33 | const transform1 = `translate(0, 0) scale(1, 1)`; | ||
| 34 | const transform2 = `translate(${dx}px, ${dy}px) scale(${rw}, ${rh})`; | ||
| 35 | const keyframes = [ | ||
| 36 | { transform: transform1, opacity: 1 }, | ||
| 37 | { transform: transform2, opacity: 0.3 }, | ||
| 38 | ] | ||
| 39 | |||
| 40 | return child.animate( | ||
| 41 | resume | ||
| 42 | ? keyframes.reverse() | ||
| 43 | : keyframes, | ||
| 44 | { | ||
| 45 | duration: 300, | ||
| 46 | easing: 'ease-in-out', | ||
| 47 | }); | ||
| 48 | } | ||