From cbe40ac1128eedcda30812285cbec003acb8adc1 Mon Sep 17 00:00:00 2001 From: Hsieh Chin Fan Date: Sat, 21 Sep 2024 16:40:22 +0800 Subject: refactor: layout class * put class Layout and OverlayLayout together * apply extend on OverlayLayout * rename layouts: "none" -> "normal", "side" -> "side-by-side" --- src/Layout.mjs | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/OverlayLayout.mjs | 107 --------------------------------------------- src/css/dumbymap.css | 4 +- src/dumbymap.mjs | 17 ++------ 4 files changed, 123 insertions(+), 122 deletions(-) create mode 100644 src/Layout.mjs delete mode 100644 src/OverlayLayout.mjs (limited to 'src') diff --git a/src/Layout.mjs b/src/Layout.mjs new file mode 100644 index 0000000..20e8a23 --- /dev/null +++ b/src/Layout.mjs @@ -0,0 +1,117 @@ +import PlainDraggable from 'plain-draggable' +import { onRemove } from './utils' + +export class Layout { + constructor(options = {}) { + if (!options.name) throw Error("Layout name is not given") + this.name = options.name + this.enterHandler = options.enterHandler + this.leaveHandler = options.leaveHandler + } + valueOf = () => this.name +} + +export class OverlayLayout extends Layout { + name = "overlay" + + enterHandler = (dumbymap) => { + const container = dumbymap.htmlHolder + const moveIntoDraggable = (block) => { + // Create draggable block + const draggableBlock = document.createElement('div') + draggableBlock.classList.add('draggable-block') + draggableBlock.innerHTML = ` +
+
\u2630
+
+
+
\u2795
+
\u2796
+
+ ` + + // Add draggable part + const draggablePart = draggableBlock.querySelector('.draggable') + draggablePart.title = 'Use middle-click to remove block' + draggablePart.onmouseup = (e) => { + if (e.button === 1) { + // Hide block with middle click + draggableBlock.style.display = "none"; + } + } + + // Set elements + draggableBlock.appendChild(draggablePart) + draggableBlock.appendChild(block) + container.appendChild(draggableBlock) + + // Add draggable instance + const draggableInstance = new PlainDraggable(draggableBlock, { + handle: draggablePart, + snap: { x: { step: 20 }, y: { step: 20 } }, + }) + + // Plus/Minus font-size of content + const plusButton = draggableBlock.querySelector('#plus-font-size') + plusButton.onclick = () => { + const fontSize = parseFloat(getComputedStyle(block).fontSize) / 16 + block.style.fontSize = `${fontSize + 0.1}rem` + } + const minusButton = draggableBlock.querySelector('#minus-font-size') + minusButton.onclick = () => { + const fontSize = parseFloat(getComputedStyle(block).fontSize) / 16 + block.style.fontSize = `${fontSize - 0.1}rem` + } + draggableInstance.onDragStart = () => { + plusButton.style.opacity = '0' + minusButton.style.opacity = '0' + } + draggableInstance.onDragEnd = () => { + plusButton.style = '' + minusButton.style = '' + } + + // Reposition draggable instance when resized + new ResizeObserver(() => { + try { + draggableInstance.position(); + } catch (_) { + null + } + }).observe(draggableBlock); + + // Callback for remove + onRemove(draggableBlock, () => { + draggableInstance.remove() + }) + + return draggableInstance + } + + // Create draggable blocks and set each position by previous one + let [x, y] = [0, 0] + dumbymap.blocks.map(moveIntoDraggable) + .forEach(draggable => { + draggable.left = x + draggable.top = y + const rect = draggable.element.getBoundingClientRect() + x += rect.width + 30 + if (x > window.innerWidth) { + y += 200 + x = x % window.innerWidth + } + }) + } + leaveHandler = (dumbymap) => { + const container = dumbymap.htmlHolder + const resumeFromDraggable = (block) => { + const draggableContainer = block.closest('.draggable-block') + if (!draggableContainer) return + container.appendChild(block) + block.removeAttribute('style') + draggableContainer.remove() + } + dumbymap.blocks.forEach(resumeFromDraggable) + } +} + diff --git a/src/OverlayLayout.mjs b/src/OverlayLayout.mjs deleted file mode 100644 index 8b4e073..0000000 --- a/src/OverlayLayout.mjs +++ /dev/null @@ -1,107 +0,0 @@ -import PlainDraggable from 'plain-draggable' -import { onRemove } from './utils' - -export class OverlayLayout { - name = "overlay" - - enterHandler = (dumbymap) => { - const container = dumbymap.htmlHolder - const moveIntoDraggable = (block) => { - // Create draggable block - const draggableBlock = document.createElement('div') - draggableBlock.classList.add('draggable-block') - draggableBlock.innerHTML = ` -
-
\u2630
-
-
-
\u2795
-
\u2796
-
- ` - - // Add draggable part - const draggablePart = draggableBlock.querySelector('.draggable') - draggablePart.title = 'Use middle-click to remove block' - draggablePart.onmouseup = (e) => { - if (e.button === 1) { - // Hide block with middle click - draggableBlock.style.display = "none"; - } - } - - // Set elements - draggableBlock.appendChild(draggablePart) - draggableBlock.appendChild(block) - container.appendChild(draggableBlock) - - // Add draggable instance - const draggableInstance = new PlainDraggable(draggableBlock, { - handle: draggablePart, - snap: { x: { step: 20 }, y: { step: 20 } }, - }) - - // Plus/Minus font-size of content - const plusButton = draggableBlock.querySelector('#plus-font-size') - plusButton.onclick = () => { - const fontSize = parseFloat(getComputedStyle(block).fontSize) / 16 - block.style.fontSize = `${fontSize + 0.1}rem` - } - const minusButton = draggableBlock.querySelector('#minus-font-size') - minusButton.onclick = () => { - const fontSize = parseFloat(getComputedStyle(block).fontSize) / 16 - block.style.fontSize = `${fontSize - 0.1}rem` - } - draggableInstance.onDragStart = () => { - plusButton.style.opacity = '0' - minusButton.style.opacity = '0' - } - draggableInstance.onDragEnd = () => { - plusButton.style = '' - minusButton.style = '' - } - - // Reposition draggable instance when resized - new ResizeObserver(() => { - try { - draggableInstance.position(); - } catch (_) { - null - } - }).observe(draggableBlock); - - // Callback for remove - onRemove(draggableBlock, () => { - draggableInstance.remove() - }) - - return draggableInstance - } - - // Create draggable blocks and set each position by previous one - let [x, y] = [0, 0] - dumbymap.blocks.map(moveIntoDraggable) - .forEach(draggable => { - draggable.left = x - draggable.top = y - const rect = draggable.element.getBoundingClientRect() - x += rect.width + 30 - if (x > window.innerWidth) { - y += 200 - x = x % window.innerWidth - } - }) - } - leaveHandler = (dumbymap) => { - const container = dumbymap.htmlHolder - const resumeFromDraggable = (block) => { - const draggableContainer = block.closest('.draggable-block') - if (!draggableContainer) return - container.appendChild(block) - block.removeAttribute('style') - draggableContainer.remove() - } - dumbymap.blocks.forEach(resumeFromDraggable) - } -} - diff --git a/src/css/dumbymap.css b/src/css/dumbymap.css index f5695f1..6c68548 100644 --- a/src/css/dumbymap.css +++ b/src/css/dumbymap.css @@ -150,7 +150,6 @@ } } -.DumbyMap[data-layout]:not([data-layout="none"]) { width: 100%; height: 100vh; margin: 0 auto; @@ -162,9 +161,10 @@ display: none; pointer-events: none; } +.DumbyMap[data-layout]:not([data-layout="normal"]) { } -.DumbyMap[data-layout="side"] { +.DumbyMap[data-layout="side-by-side"] { .SemanticHtml { flex: 50%; overflow-y: auto; diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index 4eb6bdf..63ba3ed 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs @@ -6,24 +6,15 @@ import MarkdownItTocDoneRight from 'markdown-it-toc-done-right' import LeaderLine from 'leader-line' import { renderWith, parseConfigsFromYaml } from 'mapclay' import { onRemove, animateRectTransition, throttle } from './utils' -import { OverlayLayout } from './OverlayLayout' +import { Layout, OverlayLayout } from './Layout' const docLinkSelector = 'a[href^="#"][title^="=>"]' const geoLinkSelector = 'a[href^="geo:"]' -class Layout { - constructor({ name, enterHandler = null, leaveHandler = null }) { - this.name = name - this.enterHandler = enterHandler - this.leaveHandler = leaveHandler - } - valueOf = () => this.name -} - const layouts = [ - new Layout({ name: "none" }), - new Layout({ name: "side" }), - new OverlayLayout(), + new Layout({ name: "normal" }), + new Layout({ name: "side-by-side" }), + new OverlayLayout({ name: "overlay" }), ] // FUNCTION: Get DocLinks from special anchor element {{{ -- cgit v1.2.3-70-g09d2