diff --git a/bun.lockb b/bun.lockb index 85562e1..be3af48 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 571fc0f..d274a3a 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "dependencies": { "@aklinker1/check": "^1.3.1", + "panzoom": "^9.4.3", "standard-version": "^9.5.0", "vue-tsc": "^2.0.10" } diff --git a/web/components/CutlistPreview.vue b/web/components/CutlistPreview.vue index 37ac27b..3468655 100644 --- a/web/components/CutlistPreview.vue +++ b/web/components/CutlistPreview.vue @@ -1,37 +1,50 @@ - - diff --git a/web/components/PartListItem.vue b/web/components/PartListItem.vue index 0773f30..4754a61 100644 --- a/web/components/PartListItem.vue +++ b/web/components/PartListItem.vue @@ -14,7 +14,6 @@ const height = usePx(() => props.placement.lengthM); const left = usePx(() => props.placement.leftM); const bottom = usePx(() => props.placement.bottomM); -const getPx = useGetPx(); const fontSize = usePx(() => Math.min( props.placement.widthM / 2, @@ -44,6 +43,12 @@ const showPartNumbers = useShowPartNumbers(); {{ placement.partNumber }}

- + + + diff --git a/web/components/ScaleController.vue b/web/components/ScaleController.vue index 5433bba..84de5f4 100644 --- a/web/components/ScaleController.vue +++ b/web/components/ScaleController.vue @@ -1,8 +1,15 @@ diff --git a/web/composables/useGetPx.ts b/web/composables/useGetPx.ts index 4be0d53..5a7b4e2 100644 --- a/web/composables/useGetPx.ts +++ b/web/composables/useGetPx.ts @@ -1,4 +1,3 @@ export default function () { - const scale = useScale(); - return (value: number) => `${value * 500 * scale.value}px`; + return (value: number) => `${value * 500}px`; } diff --git a/web/composables/usePanZoom.ts b/web/composables/usePanZoom.ts new file mode 100644 index 0000000..eec09fa --- /dev/null +++ b/web/composables/usePanZoom.ts @@ -0,0 +1,51 @@ +import type { PanZoom } from 'panzoom'; +import panzoom from 'panzoom'; + +export default function (container: Ref) { + let instance = ref(); + const scale = ref(); + + whenever(container, (container) => { + instance.value = panzoom(container, { + autocenter: true, + minZoom: 0.2, + maxZoom: 10, + }); + scale.value = instance.value.getTransform().scale; + instance.value.on('zoom', () => { + scale.value = instance.value?.getTransform().scale; + }); + }); + whenever( + () => !container.value, + () => { + instance.value?.dispose(); + }, + ); + onUnmounted(() => { + instance.value?.dispose(); + }); + + const setZoom = (cb: (scale: number) => number, x?: number, y?: number) => { + if (instance.value == null) return; + const current = instance.value.getTransform(); + const currentScale = current.scale; + const newScale = cb(current.scale); + instance.value?.smoothZoom( + x ?? current.x, + y ?? current.y, + newScale / currentScale, + ); + }; + const zoomBy = (increment: number) => setZoom((scale) => scale + increment); + + return { + scale, + zoomIn: () => zoomBy(0.1), + zoomOut: () => zoomBy(-0.1), + resetZoom: () => { + setZoom(() => 1); + instance.value?.smoothMoveTo(0, 0); + }, + }; +} diff --git a/web/composables/useScale.ts b/web/composables/useScale.ts deleted file mode 100644 index b77105e..0000000 --- a/web/composables/useScale.ts +++ /dev/null @@ -1 +0,0 @@ -export default createGlobalState(() => useSessionStorage('@cutlist/scale', 1)); diff --git a/web/composables/useScaleControls.ts b/web/composables/useScaleControls.ts deleted file mode 100644 index ffbcd65..0000000 --- a/web/composables/useScaleControls.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default function () { - const scale = useScale(); - return { - zoomIn: () => void (scale.value += 0.1), - zoomOut: () => void (scale.value = Math.max(scale.value - 0.1, 0.1)), - resetZoom: () => void (scale.value = 1), - }; -} diff --git a/web/pages/index.vue b/web/pages/index.vue index f4137e7..d22103f 100644 --- a/web/pages/index.vue +++ b/web/pages/index.vue @@ -7,23 +7,23 @@ const isExpanded = useIsExpanded(); -
- -
- -
- - -
- - -
-
+
+ +