Changes
3 changed files (+93/-23)
-
-
@@ -1,6 +1,6 @@--- createdAt: 2024-04-15T23:00:00+09:00 updatedAt: 2024-05-10T01:00:00+09:00 updatedAt: 2024-05-15T14:21:00+09:00 --- ## v1.0
-
@@ -33,7 +33,7 @@ - [x] Use HTML elements for JSONCanvas file/text nodes- [x] Client script to retain open/close state of document tree - [ ] Client script to sync active table of contents entry to current scroll position - [x] Client script to close site menu on navigation event - [ ] Client script for JSONCanvas gestures and UI - [x] Client script for JSONCanvas gestures and UI ## v0.1
-
-
-
@@ -9,7 +9,7 @@ /** @jsx s */import { s } from "../../../deps/esm.sh/hastscript/mod.ts"; import { buildClasses, css } from "../css.ts"; import { buildClasses, css, cx } from "../css.ts"; function cls( ...classNames: readonly (string | null | false | undefined)[]
-
@@ -357,3 +357,44 @@ <line x1="4" x2="20" y1="18" y2="18" /></svg> ); } export function zoomIn({ className, ...rest }: LucideIconProps = {}) { return ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" {...rest} class={cx(c.icon, className)} > <circle cx="11" cy="11" r="8" /> <line x1="21" x2="16.65" y1="21" y2="16.65" /> <line x1="11" x2="11" y1="8" y2="14" /> <line x1="8" x2="14" y1="11" y2="11" /> </svg> ); } export function zoomOut({ className, ...rest }: LucideIconProps = {}) { return ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" {...rest} class={cx(c.icon, className)} > <circle cx="11" cy="11" r="8" /> <line x1="21" x2="16.65" y1="21" y2="16.65" /> <line x1="8" x2="14" y1="11" y2="11" /> </svg> ); }
-
-
-
@@ -12,6 +12,7 @@import type { BuildContext } from "../context.ts"; import { buildClasses, css, join } from "../css.ts"; import { lucideIconStyles, zoomIn, zoomOut } from "../icons/lucide.tsx"; import { layout, layoutScript, layoutStyles } from "../widgets/layout.tsx"; import { documentTree,
-
@@ -34,6 +35,7 @@ "scrollableChild","layout", "keyShortcutTip", "gestureEnabledContainer", "scale", ]); const ownStyles = css`
-
@@ -64,7 +66,12 @@ }.${c.controls} { display: flex; align-items: center; gap: 4px 0.25em; line-height: 1; font-size: 0.9rem; color: var(--color-fg-sub); } .${c.controlButton} {
-
@@ -75,8 +82,9 @@ align-items: center;width: 1.5rem; height: 1.5rem; aspect-ratio: 1 / 1; border: 1px solid var(--color-border); font-size: 0.9rem; border: none; padding: 0; margin: 0; background: transparent; border-radius: 2px;
-
@@ -131,9 +139,18 @@.${c.gestureEnabledContainer}:focus-visible .${c.keyShortcutTip} { display: inline-block; } .${c.scale} { display: inline-block; min-width: 5ch; font-variant-numeric: tabular-nums; text-align: center; } `; export const jsonCanvasPageStyles = join( lucideIconStyles, layoutStyles, documentTreeStyles, footerStyles,
-
@@ -143,7 +160,7 @@ );const ownScript = ` let scale = 1.0; const SCALE_MIN = 0.1; const SCALE_MIN = 0.3; const SCALE_MAX = 2.0; let tx = 0.0; let ty = 0.0;
-
@@ -160,8 +177,14 @@ const TOUCH_PAN = 1;const TOUCH_ZOOM = 2; let touchState = { type: TOUCH_NONE }; function clampScale(v) { return Math.max(SCALE_MIN, Math.min(SCALE_MAX, v)); const scaleLabel = document.getElementById("__macana_jc_scale"); function setScale(v) { scale = Math.max(SCALE_MIN, Math.min(SCALE_MAX, v)); if (scaleLabel) { scaleLabel.textContent = Math.round(scale * 100) + "%"; } } for (const child of document.getElementsByClassName("${c.scrollableChild}")) {
-
@@ -213,10 +236,10 @@ }switch (ev.key) { case "-": scale = clampScale(scale - 0.05); setScale(scale - 0.05); break; case "+": scale = clampScale(scale + 0.05); setScale(scale + 0.05); break; case "ArrowLeft": tx += 10 / scale;
-
@@ -284,7 +307,7 @@ break;} const prevScale = scale; scale = clampScale(scale * (1 - deltaY * 0.01)); setScale(scale * (1 - deltaY * 0.01)); if (vw > 0 && vh > 0) { let offsetX = ev.offsetX;
-
@@ -381,7 +404,7 @@ if (dist === null) {return; } scale = clampScale(touchState.initialScale * (dist / touchState.initialDist)); setScale(touchState.initialScale * (dist / touchState.initialDist)); applyTransformToCanvas(); return; }
-
@@ -426,7 +449,7 @@ if (canvas) {if (vw > 0 && vh > 0) { const rect = canvas.getBoundingClientRect(); scale = clampScale(Math.min(vw / rect.width, vh / rect.height)); setScale(Math.min(vw / rect.width, vh / rect.height)); } canvas.style.position = "absolute";
-
@@ -444,22 +467,25 @@ + \` scale(\${scale.toFixed(8)})\`+ \` translate(\${tx}px,\${ty}px)\`; } const controls = document.getElementById("__macana_jc_cs"); if (controls) { controls.style.display = ""; } const zoomInButton = document.getElementById("__macana_jc_in"); if (zoomInButton) { zoomInButton.style.display = ""; zoomInButton.addEventListener("click", ev => { ev.preventDefault(); scale = clampScale(scale + 0.1); setScale(scale + 0.1); applyTransformToCanvas(); }); } const zoomOutButton = document.getElementById("__macana_jc_out"); if (zoomOutButton) { zoomOutButton.style.display = ""; zoomOutButton.addEventListener("click", ev => { ev.preventDefault(); scale = clampScale(scale - 0.1); setScale(scale - 0.1); applyTransformToCanvas(); }); }
-
@@ -514,27 +540,30 @@ data: content,scrollClassName: c.scrollableChild, })} </div> <p class={c.keyShortcutTip} aria-hidden="true"> <p class={c.keyShortcutTip}> Use arrow keys to move viewport, <kbd>-</kbd>{" "} key to zoom-out and <kbd>+</kbd> key to zoom-in. </p> </div> <div class={c.meta}> <h1 class={c.title}>{context.document.metadata.title}</h1> <div class={c.controls}> <div id="__macana_jc_cs" class={c.controls} style="display:none;"> <button id="__macana_jc_out" class={c.controlButton} style="display:none;" title="Zoom out" > <span>-</span> {zoomOut()} </button> <span id="__macana_jc_scale" class={c.scale} aria-live="polite"> 100% </span> <button id="__macana_jc_in" class={c.controlButton} style="display:none;" title="Zoom in" > <span>+</span> {zoomIn()} </button> </div> </div>
-