Spaces:
Runtime error
Runtime error
File size: 3,575 Bytes
70b8e47 66ed450 03bb246 aa3e783 32561d8 66ed450 560b99e 809d458 66ed450 560b99e aa3e783 560b99e 66ed450 35946a9 e5b9b7e 32561d8 e5b9b7e a392773 66ed450 560b99e a392773 a6e7e8f 809d458 a392773 66ed450 560b99e 66ed450 1d701d3 66ed450 70b8e47 aa3e783 5fc8a26 03bb246 5fc8a26 03bb246 aa3e783 560b99e 66ed450 32561d8 e5b9b7e 32561d8 e5b9b7e 32561d8 66ed450 32561d8 70b8e47 e5b9b7e 66ed450 560b99e 70b8e47 560b99e 70b8e47 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
<script lang="ts">
import { zoom, type ZoomTransform, zoomIdentity } from 'd3-zoom';
import { select } from 'd3-selection';
import { onMount } from 'svelte';
import { PUBLIC_UPLOADS } from '$env/static/public';
import {
currZoomTransform,
myPresence,
isPrompting,
clickedPosition,
imagesList
} from '$lib/store';
const height = 512 * 5;
const width = 512 * 5;
let canvasEl: HTMLCanvasElement;
export { canvasEl as value };
let value = canvasEl;
let containerEl: HTMLDivElement;
let canvasCtx: CanvasRenderingContext2D;
$: if ($imagesList) {
renderImages($imagesList);
}
onMount(() => {
const scale = width / containerEl.clientWidth;
const zoomHandler = zoom()
.scaleExtent([1 / scale / 1.5, 1])
// .extent([
// [0, 0],
// [width, height]
// ])
.translateExtent([
[-width * 0.1, -height * 0.1],
[width * 1.1, height * 1.1]
])
.tapDistance(10)
.on('zoom', zoomed);
select(canvasEl.parentElement)
.call(zoomHandler as any)
.on('dblclick.zoom', () => {
$isPrompting = true;
$clickedPosition = $myPresence.cursor;
console.log('clicked', $clickedPosition);
return null;
})
// .call(zoomHandler.scaleTo as any, 1 / scale)
.on('pointermove', handlePointerMove)
.on('pointerleave', handlePointerLeave);
canvasCtx = canvasEl.getContext('2d') as CanvasRenderingContext2D;
canvasCtx.strokeStyle = 'blue';
canvasCtx.lineWidth = 10;
canvasCtx.strokeRect(0, 0, width, height);
});
function renderImages(imagesList) {
const images = [...imagesList.toImmutable()].sort((a, b) => a.date - b.date);
Promise.all(
images.map(
({ imgURL, position }) =>
new Promise((resolve) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
resolve({ img, position });
};
const url = imgURL.split('/');
img.src = `${PUBLIC_UPLOADS}/${url.slice(3).join('/')}`;
})
)
).then((images) => {
images.forEach(({ img, position }) => {
canvasCtx.drawImage(img, position.x, position.y, img.width, img.height);
});
});
}
function zoomed(e: Event) {
const transform = ($currZoomTransform = e.transform);
canvasEl.style.transform = `translate(${transform.x}px, ${transform.y}px) scale(${transform.k})`;
}
const r = 8;
function round(p, n) {
return p % n < n / 2 ? p - (p % n) : p + n - (p % n);
}
const grid = 10;
// Update cursor presence to current pointer location
function handlePointerMove(event: PointerEvent) {
event.preventDefault();
const x = Math.round($currZoomTransform.invertX(event.layerX) / grid) * grid;
const y = Math.round($currZoomTransform.invertY(event.layerY) / grid) * grid;
// const x = Math.round(event.layerX / grid) * grid; //round(Math.max(r, Math.min(512 * 5 - r, event.clientX)), 100);
// const y = Math.round(event.layerY / grid) * grid; //round(Math.max(r, Math.min(512 * 5 - r, event.clientY)), 100);
// const x = round(Math.max(r, Math.min(512 * 5 - r, event.clientX)), grid);
// const y = round(Math.max(r, Math.min(512 * 5 - r, event.clientY)), grid);
$myPresence = {
cursor: {
x,
y
}
};
}
// When the pointer leaves the page, set cursor presence to null
function handlePointerLeave() {
$myPresence = {
cursor: null
};
}
</script>
<div bind:this={containerEl} class="absolute top-0 left-0 right-0 bottom-0 overflow-hidden z-0">
<canvas bind:this={canvasEl} {width} {height} class="absolute top-0 left-0" />
</div>
<style lang="postcss" scoped>
canvas {
transform-origin: 0 0;
}
</style>
|