diff options
author | Hsieh Chin Fan <pham@topo.tw> | 2024-09-20 13:22:58 +0800 |
---|---|---|
committer | Hsieh Chin Fan <pham@topo.tw> | 2024-09-20 15:59:58 +0800 |
commit | d87ed12b603e6a4ffdbe666d984bb464df9b620f (patch) | |
tree | efc0b7e925d3129fb8a0712d02603fc7189083cd /src/dumbymap.mjs | |
parent | 7b482c3f1d7c3b09bb9592c9926937b9887f6217 (diff) |
feat: add throttle for DOMRect animation
Diffstat (limited to 'src/dumbymap.mjs')
-rw-r--r-- | src/dumbymap.mjs | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index 9a38e24..6e4c00e 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs | |||
@@ -6,10 +6,8 @@ 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 | import { onRemove, animateRectTransition, throttle } from './utils' |
10 | 10 | ||
11 | // Utils {{{ | ||
12 | // }}} | ||
13 | // FUNCTION: Get DocLinks from special anchor element {{{ | 11 | // FUNCTION: Get DocLinks from special anchor element {{{ |
14 | 12 | ||
15 | const docLinkSelector = 'a[href^="#"][title^="=>"]' | 13 | const docLinkSelector = 'a[href^="#"][title^="=>"]' |
@@ -229,6 +227,9 @@ export const generateMaps = async (container, callback) => { | |||
229 | showcase.classList.add('Showcase') | 227 | showcase.classList.add('Showcase') |
230 | 228 | ||
231 | // Focus Map {{{ | 229 | // Focus Map {{{ |
230 | const toShowcaseWithThrottle = throttle(animateRectTransition, 300) | ||
231 | const fromShowCaseWithThrottle = throttle(animateRectTransition, 300) | ||
232 | |||
232 | const mapFocusObserver = () => new MutationObserver((mutations) => { | 233 | const mapFocusObserver = () => new MutationObserver((mutations) => { |
233 | const mutation = mutations.at(-1) | 234 | const mutation = mutations.at(-1) |
234 | const target = mutation.target | 235 | const target = mutation.target |
@@ -238,31 +239,41 @@ export const generateMaps = async (container, callback) => { | |||
238 | if (shouldBeInShowcase) { | 239 | if (shouldBeInShowcase) { |
239 | if (showcase.contains(target)) return | 240 | if (showcase.contains(target)) return |
240 | 241 | ||
241 | // Placeholder for map in Showcase, it should has the same rect | 242 | // Placeholder for map in Showcase, it should has the same DOMRect |
242 | const placeholder = target.cloneNode(true) | 243 | const placeholder = target.cloneNode(true) |
243 | placeholder.classList.remove('map-container') | 244 | placeholder.classList.remove('map-container') |
244 | placeholder.setAttribute('data-placeholder', target.id) | 245 | placeholder.setAttribute('data-placeholder', target.id) |
245 | target.parentElement.replaceChild(placeholder, target) | 246 | target.parentElement.replaceChild(placeholder, target) |
246 | 247 | ||
247 | // To fit showcase, remove all inline style | 248 | // To fit showcase, remove all inline style |
248 | target.style = "" | 249 | target.removeAttribute('style') |
249 | showcase.appendChild(target) | 250 | showcase.appendChild(target) |
250 | 251 | ||
251 | // Resume rect from Semantic HTML to Showcase, with animation | 252 | // Resume rect from Semantic HTML to Showcase, with animation |
252 | animateRectTransition(target, placeholder.getBoundingClientRect(), true) | 253 | toShowcaseWithThrottle(target, placeholder.getBoundingClientRect(), { |
254 | duration: 300, | ||
255 | resume: true | ||
256 | }) | ||
253 | } else if (showcase.contains(target)) { | 257 | } else if (showcase.contains(target)) { |
254 | const placeholder = htmlHolder.querySelector(`[data-placeholder="${target.id}"]`) | 258 | const placeholder = htmlHolder.querySelector(`[data-placeholder="${target.id}"]`) |
255 | if (!placeholder) throw Error(`Cannot fine placeholder for map "${target.id}"`) | 259 | if (!placeholder) throw Error(`Cannot fine placeholder for map "${target.id}"`) |
260 | const animation = fromShowCaseWithThrottle(target, placeholder.getBoundingClientRect(), { | ||
261 | duration: 300 | ||
262 | }) | ||
256 | 263 | ||
257 | const afterAnimation = () => { | 264 | const afterAnimation = () => { |
258 | placeholder.parentElement.replaceChild(target, placeholder) | 265 | placeholder.parentElement.replaceChild(target, placeholder) |
259 | target.style = placeholder.style.cssText | 266 | target.style = placeholder.style.cssText |
260 | placeholder.remove() | 267 | placeholder.remove() |
261 | } | 268 | } |
262 | animateRectTransition(target, placeholder.getBoundingClientRect()) | 269 | |
263 | .finished | 270 | if (animation) { |
264 | .then(afterAnimation) | 271 | animation.finished |
265 | .catch(afterAnimation) | 272 | .then(afterAnimation) |
273 | .catch(afterAnimation) | ||
274 | } else { | ||
275 | afterAnimation() | ||
276 | } | ||
266 | } | 277 | } |
267 | }) | 278 | }) |
268 | // }}} | 279 | // }}} |