From 86a51d3cf912c90166b75bb4b48f4b3ab647bc5e Mon Sep 17 00:00:00 2001 From: flop Date: Sat, 30 May 2026 13:35:20 +0200 Subject: [PATCH] feat: drag and drop support --- ts/src/browser.ts | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/ts/src/browser.ts b/ts/src/browser.ts index de713f6..1a3c678 100644 --- a/ts/src/browser.ts +++ b/ts/src/browser.ts @@ -534,6 +534,53 @@ const PixelCanvas: m.Component<{ img: MonoDisplay.MonoFormatPixelImage; onpaint: onmousemove: (e: MouseEvent) => { if (state.drawing) paint(e); }, onmouseup: () => { state.drawing = false; }, onmouseleave: () => { state.drawing = false; }, + ondragover: (e: DragEvent) => { + e.preventDefault(); + e.dataTransfer!.dropEffect = "copy"; + }, + + ondrop: (e: DragEvent) => { + e.preventDefault(); + const file = e.dataTransfer?.files[0]; + if (!file || !file.type.startsWith("image/")) return; + + const url = URL.createObjectURL(file); + const htmlImg = new Image(); + htmlImg.onload = () => { + // Draw the dropped image into an offscreen canvas to read pixel data + const offscreen = document.createElement("canvas"); + offscreen.width = htmlImg.width; + offscreen.height = htmlImg.height; + const ctx = offscreen.getContext("2d")!; + ctx.drawImage(htmlImg, 0, 0); + + const imageData = ctx.getImageData(0, 0, htmlImg.width, htmlImg.height); + + // Convert to your pixel format — adjust this to match your img structure + const scale = Math.min(1, 120 / htmlImg.width, 60 / htmlImg.height); + const w = Math.round(htmlImg.width * scale); + const h = Math.round(htmlImg.height * scale); + + offscreen.width = w; + offscreen.height = h; + ctx.drawImage(htmlImg, 0, 0, w, h); // scales the image down while drawing + img.width = w; + img.height = h; + // then read imageData from the scaled offscreen canvas as before + img.pixels = new Uint8Array(w * h).map((_, i) => { + const r = imageData.data[i * 4]; + const g = imageData.data[i * 4 + 1]; + const b = imageData.data[i * 4 + 2]; + const a = imageData.data[i * 4 + 3]; + // transparent = 0, dark pixels = 1, light pixels = 0 + return a > 128 && (r * 299 + g * 587 + b * 114) < 128_000 ? 0 : 1; + }); + + URL.revokeObjectURL(url); + m.redraw(); + }; + htmlImg.src = url; + }, }); }, };