diff --git a/src/lib/Structure.svelte b/src/lib/Structure.svelte index 777b413..8e41b10 100644 --- a/src/lib/Structure.svelte +++ b/src/lib/Structure.svelte @@ -13,6 +13,10 @@ export let camera_position: [number, number, number] = [10, 10, 10] // zoom level of the camera export let zoom: number = 1 / 50 + // zoom speed. set to 0 to disable zooming. + export let zoom_speed: number = 0.3 + // pan speed. set to 0 to disable panning. + export let pan_speed: number = 0.3 // whether to show the controls panel export let show_controls: boolean = false // TODO whether to make the canvas fill the whole screen @@ -38,16 +42,24 @@ } } - $: ({ a, b, c } = structure?.lattice ?? {}) + $: ({ a, b, c } = structure?.lattice ?? { a: 0, b: 0, c: 0 }) const on_window_click = (node: (HTMLElement | null)[], cb: () => void) => (event: MouseEvent) => { - if (!node || !event.target) return - - if (node && !node.some((n) => n?.contains(event.target as Node))) { - cb() - } + if (!node || !event.target) return // ignore invalid input + // ignore clicks inside any of the nodes + if (node && node.some((n) => n?.contains(event.target as Node))) return + cb() // invoke callback } + + const initial_zoom = zoom + let orbit_controls: OrbitControls + $: orbit_controls?.saveState() // record orbit target for reset + + const reset_camera = () => { + zoom = initial_zoom + orbit_controls?.reset() + } - -
- - - - {#if show_cell} +
+
+ + +
+ +
- {/if} - -
+ + + {#if show_cell} + + {/if} + + + + + - + 0} + zoomSpeed={zoom_speed} + enablePan={pan_speed > 0} + panSpeed={pan_speed} + target={{ x: a / 2, y: b / 2, z: c / 2 }} + bind:controls={orbit_controls} + /> @@ -159,26 +191,31 @@ container-type: inline-size; } - .controls-toggle { + .controls { position: absolute; - z-index: var(--svelte-controls-toggle-z-index, 1); - top: var(--svelte-controls-toggle-top, 8pt); - right: var(--svelte-controls-toggle-right, 8pt); + z-index: var(--controls-z-index, 1); + top: var(--controls-top, 8pt); + right: var(--controls-right, 8pt); } - section.controls { + .controls > section { + display: flex; + gap: 1ex; + } + .controls > form { display: grid; - position: absolute; - top: 5pt; - right: 5pt; + right: 0; + margin-top: 22px; background-color: rgba(0, 0, 0, 0.6); padding: 6pt 9pt; border-radius: 3pt; visibility: hidden; opacity: 0; transition: visibility 0.1s, opacity 0.1s linear; + width: 18em; + box-sizing: border-box; max-width: 40cqw; } - section.controls.open { + .controls > form.open { visibility: visible; opacity: 1; }