From cb296a5fe41077dc353ee0d49ceb89ba01164634 Mon Sep 17 00:00:00 2001 From: Logan Date: Wed, 6 Nov 2024 02:02:36 -0600 Subject: [PATCH] Implemented zooming and panning --- static/canvas.js | 75 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/static/canvas.js b/static/canvas.js index 99de9e9..236e9cb 100644 --- a/static/canvas.js +++ b/static/canvas.js @@ -4,8 +4,29 @@ const ctx = canvas.getContext("2d"); const CANVAS_SIZE = 500; const DATA_SIZE = 200; let scale = 1; +let offx = 0; +let offy = 0; + +let clickx = 0; +let clicky = 0; + +let mouseClicked = false; // Array of [red, blue, green, transparency] * width * height -const image = new ImageData(DATA_SIZE, DATA_SIZE); +let image = new ImageData(DATA_SIZE, DATA_SIZE); +// Drawable image +let bitmap = null; + +window.addEventListener("load", async (e) => { + // Create drawable image, update it every half second + await redraw(); + setInterval(redraw, 500); + setInterval(draw, 500); +}); + + +async function redraw() { + bitmap = await createImageBitmap(image); +} // Color is an array of four numbers 0-255 (RGB + transparency) function setPixel(data, x, y, color) { @@ -15,24 +36,28 @@ function setPixel(data, x, y, color) { } } -async function draw(image) { +function draw() { ctx.fillStyle = "rgb(0 0 0 255)"; ctx.clearRect(0, 0, canvas.width, canvas.height); let drawScale = CANVAS_SIZE / DATA_SIZE * scale; - let bitmap = await createImageBitmap(image); ctx.imageSmoothingEnabled = false; ctx.scale(drawScale, drawScale); - ctx.drawImage(bitmap, 0, 0); + ctx.drawImage(bitmap, offx, offy); ctx.setTransform(1, 0, 0, 1, 0, 0); } canvas.addEventListener("wheel", async (e) => { + let oldScale = scale; if (e.deltaY < 0) { scale += 0.1; } else if (e.deltaY > 0) { scale -= 0.1; } - await draw(image); + /* + offX += (DATA_SIZE * scale - DATA_SIZE * oldScale) / 2; + offY += (DATA_SIZE * scale - DATA_SIZE * oldScale) / 2; + */ + draw(image); }); canvas.addEventListener("contextmenu", (e) => { @@ -42,17 +67,41 @@ canvas.addEventListener("contextmenu", (e) => { canvas.addEventListener("mousedown", async (e) => { // Left click if (e.button == 0) { + mouseClicked = true; + setTimeout(() => { + mouseClicked = false; + }, 200); + } +}); + +canvas.addEventListener("mouseup", async (e) => { + if (e.button == 0 && mouseClicked) { + mouseClicked = false; + + clickx = e.clientX; + clicky = e.clientY; + let x = e.clientX - canvas.getBoundingClientRect().left; let y = e.clientY - canvas.getBoundingClientRect().top; - let cx = Math.round(x / (CANVAS_SIZE * scale) * DATA_SIZE); - let cy = Math.round(y / (CANVAS_SIZE * scale) * DATA_SIZE); - - setPixel(image.data, cx, cy, [255, 0, 0, 255]); - await draw(image); - } - // Right click - else if (e.button == 2) { + let cx = Math.round(x / (CANVAS_SIZE * scale) * DATA_SIZE - offx); + let cy = Math.round(y / (CANVAS_SIZE * scale) * DATA_SIZE - offy); + console.log(cx, cy); + if (cx < 0 || cx > CANVAS_SIZE || cy < 0 || cy > CANVAS_SIZE) { + return; + } + setPixel(image.data, cx, cy, [255, 0, 0, 255]); + await redraw(); + draw(); } }); + +canvas.addEventListener("mousemove", async (e) => { + // `buttons` is a bitflag for some dumb reason + if (e.buttons & 1) { + offx += e.movementX * (1.0 / scale) * 0.45; + offy += e.movementY * (1.0 / scale) * 0.45; + draw(image); + } +});