diff options
author | Hsieh Chin Fan <pham@topo.tw> | 2024-09-15 00:16:02 +0800 |
---|---|---|
committer | Hsieh Chin Fan <pham@topo.tw> | 2024-09-15 11:02:28 +0800 |
commit | e25db413c595623b18315bd716ba7171f32ccc51 (patch) | |
tree | 867066377fc73dd802eb3f2bff78d5bc86d4f431 /src | |
parent | 8aadc8fd3b69fbd8a030e88426816c38ca32f4af (diff) |
feat: Improve draggable behavior in overlay layout
* Set position=absolute on each block, so they won't affect each others'
y value when display=none (about Block Formatting Context)
* Add title tooltip for removing block
* Simple logic to set initial position of block by their width
Diffstat (limited to 'src')
-rw-r--r-- | src/css/dumbymap.css | 1 | ||||
-rw-r--r-- | src/dumbymap.mjs | 60 |
2 files changed, 40 insertions, 21 deletions
diff --git a/src/css/dumbymap.css b/src/css/dumbymap.css index 1dc7a09..8e28af5 100644 --- a/src/css/dumbymap.css +++ b/src/css/dumbymap.css | |||
@@ -142,6 +142,7 @@ | |||
142 | 142 | ||
143 | > .draggable-block { | 143 | > .draggable-block { |
144 | box-sizing: content-box; | 144 | box-sizing: content-box; |
145 | position: absolute; | ||
145 | width: fit-content; | 146 | width: fit-content; |
146 | max-height: 50vh; | 147 | max-height: 50vh; |
147 | overflow: scroll; | 148 | overflow: scroll; |
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index f9a999b..4d4628d 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs | |||
@@ -294,6 +294,26 @@ export const generateMaps = async (container) => { | |||
294 | console.info(renderInfo) | 294 | console.info(renderInfo) |
295 | 295 | ||
296 | //}}} | 296 | //}}} |
297 | // Draggable Blocks{{{ | ||
298 | // Add draggable part for blocks | ||
299 | htmlHolder.blocks = Array.from(htmlHolder.querySelectorAll('.draggable-block')) | ||
300 | htmlHolder.blocks.forEach(block => { | ||
301 | // Add draggable part | ||
302 | const draggablePart = document.createElement('div'); | ||
303 | draggablePart.classList.add('draggable') | ||
304 | draggablePart.textContent = '☰' | ||
305 | draggablePart.title = 'Use middle-click to remove block' | ||
306 | block.insertBefore(draggablePart, block.firstChild) | ||
307 | block.draggablePart = draggablePart | ||
308 | |||
309 | draggablePart.onmouseup = (e) => { | ||
310 | if (e.button === 1) { | ||
311 | block.style.display = "none"; | ||
312 | } | ||
313 | } | ||
314 | }) | ||
315 | |||
316 | // }}} | ||
297 | // CSS observer {{{ | 317 | // CSS observer {{{ |
298 | 318 | ||
299 | // Set focusArea | 319 | // Set focusArea |
@@ -323,20 +343,6 @@ export const generateMaps = async (container) => { | |||
323 | } | 343 | } |
324 | } | 344 | } |
325 | 345 | ||
326 | // Add draggable part for blocks | ||
327 | htmlHolder.blocks = Array.from(htmlHolder.querySelectorAll('.draggable-block')) | ||
328 | htmlHolder.blocks.forEach(block => { | ||
329 | const draggablePart = document.createElement('div'); | ||
330 | draggablePart.classList.add('draggable') | ||
331 | draggablePart.textContent = '☰' | ||
332 | |||
333 | // TODO Better way to close block | ||
334 | draggablePart.onmouseup = (e) => { | ||
335 | if (e.button === 1) block.style.display = "none"; | ||
336 | } | ||
337 | block.insertBefore(draggablePart, block.firstChild) | ||
338 | }) | ||
339 | |||
340 | // observe layout change | 346 | // observe layout change |
341 | const layoutObserver = new MutationObserver(() => { | 347 | const layoutObserver = new MutationObserver(() => { |
342 | const layout = container.getAttribute('data-layout') | 348 | const layout = container.getAttribute('data-layout') |
@@ -363,17 +369,29 @@ export const generateMaps = async (container) => { | |||
363 | } | 369 | } |
364 | 370 | ||
365 | if (layout === 'overlay') { | 371 | if (layout === 'overlay') { |
366 | htmlHolder.blocks.forEach(block => { | 372 | let x = 0; |
367 | block.draggableInstance = new PlainDraggable(block, { handle: block.querySelector('.draggable') }) | 373 | let y = 0; |
368 | block.draggableInstance.snap = { x: { step: 20 }, y: { step: 20 } } | 374 | htmlHolder.blocks.forEach(block =>{ |
369 | // block.draggableInstance.onDragEnd = () => { | 375 | block.draggableInstance = new PlainDraggable(block, { |
370 | // links(block).forEach(link => link.line.position()) | 376 | handle: block.draggablePart, |
371 | // } | 377 | snap: { x: { step: 20 }, y: { step: 20 } }, |
378 | autoScroll: false, | ||
379 | }) | ||
380 | // block.style.transform = `translate(${x}px, ${y}px)` | ||
381 | block.style.left = `${x}px` | ||
382 | block.style.top = `${y}px` | ||
383 | x += parseInt(window.getComputedStyle(block).width) + 50 | ||
384 | if (x > window.innerWidth) { | ||
385 | y += 200 | ||
386 | x = x % window.innerWidth | ||
387 | } | ||
372 | }) | 388 | }) |
373 | } else { | 389 | } else { |
374 | htmlHolder.blocks.forEach(block => { | 390 | htmlHolder.blocks.forEach(block => { |
375 | block.style.transform = 'none' | 391 | block.style.transform = 'none' |
376 | block.draggableInstance?.remove() | 392 | try { |
393 | block.draggableInstance?.remove() | ||
394 | } catch (err) { } | ||
377 | }) | 395 | }) |
378 | } | 396 | } |
379 | }); | 397 | }); |