upend/webui/src/components/EntitySelect.svelte

93 lines
2.1 KiB
Svelte
Raw Normal View History

<script lang="ts" context="module">
import { writable } from "svelte/store";
export const selected = writable<string[]>([]);
</script>
<script lang="ts">
import { onMount } from "svelte";
let canvas: HTMLCanvasElement;
onMount(() => {
const ctx = canvas.getContext("2d");
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener("resize", resizeCanvas);
resizeCanvas();
// if ctrl is pressed while right button is dragged over screen, draw a red line on canvas
let selecting = false;
document.addEventListener("mousedown", (ev) => {
if (ev.ctrlKey) {
ev.preventDefault();
selecting = true;
ctx.strokeStyle = "#dc322f77";
ctx.lineWidth = 7;
ctx.beginPath();
ctx.moveTo(ev.clientX, ev.clientY);
}
});
document.addEventListener("mousemove", (ev) => {
if (selecting) {
ev.preventDefault();
const el = document.elementFromPoint(
ev.clientX,
ev.clientY,
) as HTMLElement;
const addressElement = el.closest("[data-address]") as
| HTMLElement
| undefined;
if (addressElement) {
const address = addressElement.dataset.address;
selected.update((selected) => {
if (!selected.includes(address)) {
return [...selected, address];
} else {
return selected;
}
});
}
ctx.lineTo(ev.clientX, ev.clientY);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(ev.clientX, ev.clientY);
}
});
document.addEventListener("mouseup", () => {
selecting = false;
ctx.clearRect(0, 0, canvas.width, canvas.height);
});
});
</script>
<div class="selectIndicator">
<canvas bind:this={canvas}></canvas>
</div>
<style lang="scss">
.selectIndicator {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
pointer-events: none;
canvas {
width: 100%;
height: 100%;
}
}
</style>