Spaces:
Runtime error
Runtime error
center zoom free translation
Browse files- frontend/package.json +2 -0
- frontend/src/lib/PaintCanvas.svelte +45 -9
frontend/package.json
CHANGED
|
@@ -17,6 +17,7 @@
|
|
| 17 |
"@tailwindcss/forms": "^0.5.3",
|
| 18 |
"@tailwindcss/line-clamp": "^0.4.2",
|
| 19 |
"@types/cookie": "^0.5.1",
|
|
|
|
| 20 |
"@types/d3-drag": "^3.0.1",
|
| 21 |
"@types/d3-selection": "^3.0.3",
|
| 22 |
"@types/d3-zoom": "^3.0.1",
|
|
@@ -42,6 +43,7 @@
|
|
| 42 |
"dependencies": {
|
| 43 |
"@fontsource/fira-mono": "^4.5.0",
|
| 44 |
"@liveblocks/client": "^0.18.2",
|
|
|
|
| 45 |
"d3-drag": "^3.0.0",
|
| 46 |
"d3-selection": "^3.0.0",
|
| 47 |
"d3-zoom": "^3.0.0",
|
|
|
|
| 17 |
"@tailwindcss/forms": "^0.5.3",
|
| 18 |
"@tailwindcss/line-clamp": "^0.4.2",
|
| 19 |
"@types/cookie": "^0.5.1",
|
| 20 |
+
"@types/d3-array": "^3.0.3",
|
| 21 |
"@types/d3-drag": "^3.0.1",
|
| 22 |
"@types/d3-selection": "^3.0.3",
|
| 23 |
"@types/d3-zoom": "^3.0.1",
|
|
|
|
| 43 |
"dependencies": {
|
| 44 |
"@fontsource/fira-mono": "^4.5.0",
|
| 45 |
"@liveblocks/client": "^0.18.2",
|
| 46 |
+
"d3-array": "^3.2.0",
|
| 47 |
"d3-drag": "^3.0.0",
|
| 48 |
"d3-selection": "^3.0.0",
|
| 49 |
"d3-zoom": "^3.0.0",
|
frontend/src/lib/PaintCanvas.svelte
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
<script lang="ts">
|
| 2 |
import { zoom, zoomIdentity } from 'd3-zoom';
|
|
|
|
| 3 |
import { select } from 'd3-selection';
|
| 4 |
import { onMount } from 'svelte';
|
| 5 |
import { PUBLIC_UPLOADS } from '$env/static/public';
|
|
@@ -56,8 +57,24 @@
|
|
| 56 |
renderImages(promptImgList);
|
| 57 |
}
|
| 58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
onMount(() => {
|
| 60 |
-
const padding =
|
| 61 |
const scale =
|
| 62 |
(width + padding * 2) /
|
| 63 |
(containerEl.clientHeight > containerEl.clientWidth
|
|
@@ -65,17 +82,27 @@
|
|
| 65 |
: containerEl.clientHeight);
|
| 66 |
const zoomHandler = zoom()
|
| 67 |
.scaleExtent([1 / scale / 2, 3])
|
| 68 |
-
.translateExtent([
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
])
|
| 72 |
.tapDistance(10)
|
| 73 |
.on('zoom', zoomed);
|
| 74 |
|
| 75 |
const selection = select($canvasEl.parentElement)
|
| 76 |
.call(zoomHandler as any)
|
| 77 |
-
.call(
|
| 78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
.on('pointermove', handlePointerMove)
|
| 80 |
.on('pointerleave', handlePointerLeave);
|
| 81 |
|
|
@@ -86,8 +113,17 @@
|
|
| 86 |
(containerEl.clientHeight > containerEl.clientWidth
|
| 87 |
? containerEl.clientWidth
|
| 88 |
: containerEl.clientHeight);
|
| 89 |
-
selection.call(
|
| 90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
}
|
| 92 |
window.addEventListener('resize', zoomReset);
|
| 93 |
return () => {
|
|
|
|
| 1 |
<script lang="ts">
|
| 2 |
import { zoom, zoomIdentity } from 'd3-zoom';
|
| 3 |
+
import { min } from 'd3-array';
|
| 4 |
import { select } from 'd3-selection';
|
| 5 |
import { onMount } from 'svelte';
|
| 6 |
import { PUBLIC_UPLOADS } from '$env/static/public';
|
|
|
|
| 57 |
renderImages(promptImgList);
|
| 58 |
}
|
| 59 |
|
| 60 |
+
function to_bbox(
|
| 61 |
+
W: number,
|
| 62 |
+
H: number,
|
| 63 |
+
center: { x: number; y: number },
|
| 64 |
+
w: number,
|
| 65 |
+
h: number,
|
| 66 |
+
margin: number
|
| 67 |
+
) {
|
| 68 |
+
//https://bl.ocks.org/fabiovalse/b9224bfd64ca96c47f8cdcb57b35b8e2
|
| 69 |
+
const kw = (W - margin) / w;
|
| 70 |
+
const kh = (H - margin) / h;
|
| 71 |
+
const k = min([kw, kh]);
|
| 72 |
+
const x = W / 2 - center.x * k;
|
| 73 |
+
const y = H / 2 - center.y * k;
|
| 74 |
+
return zoomIdentity.translate(x, y).scale(k);
|
| 75 |
+
}
|
| 76 |
onMount(() => {
|
| 77 |
+
const padding = 100;
|
| 78 |
const scale =
|
| 79 |
(width + padding * 2) /
|
| 80 |
(containerEl.clientHeight > containerEl.clientWidth
|
|
|
|
| 82 |
: containerEl.clientHeight);
|
| 83 |
const zoomHandler = zoom()
|
| 84 |
.scaleExtent([1 / scale / 2, 3])
|
| 85 |
+
// .translateExtent([
|
| 86 |
+
// [-padding, -padding],
|
| 87 |
+
// [width + padding, height + padding]
|
| 88 |
+
// ])
|
| 89 |
.tapDistance(10)
|
| 90 |
.on('zoom', zoomed);
|
| 91 |
|
| 92 |
const selection = select($canvasEl.parentElement)
|
| 93 |
.call(zoomHandler as any)
|
| 94 |
+
.call(
|
| 95 |
+
zoomHandler.transform as any,
|
| 96 |
+
to_bbox(
|
| 97 |
+
containerEl.clientWidth,
|
| 98 |
+
containerEl.clientHeight,
|
| 99 |
+
{ x: width / 2, y: height / 2 },
|
| 100 |
+
width,
|
| 101 |
+
height,
|
| 102 |
+
padding
|
| 103 |
+
)
|
| 104 |
+
)
|
| 105 |
+
// .call(zoomHandler.scaleTo as any, 1 / scale)
|
| 106 |
.on('pointermove', handlePointerMove)
|
| 107 |
.on('pointerleave', handlePointerLeave);
|
| 108 |
|
|
|
|
| 113 |
(containerEl.clientHeight > containerEl.clientWidth
|
| 114 |
? containerEl.clientWidth
|
| 115 |
: containerEl.clientHeight);
|
| 116 |
+
selection.call(
|
| 117 |
+
zoomHandler.transform as any,
|
| 118 |
+
to_bbox(
|
| 119 |
+
containerEl.clientWidth,
|
| 120 |
+
containerEl.clientHeight,
|
| 121 |
+
{ x: width / 2, y: height / 2 },
|
| 122 |
+
width,
|
| 123 |
+
height,
|
| 124 |
+
padding
|
| 125 |
+
)
|
| 126 |
+
);
|
| 127 |
}
|
| 128 |
window.addEventListener('resize', zoomReset);
|
| 129 |
return () => {
|