Implemented zooming and panning

This commit is contained in:
Logan 2024-11-06 02:02:36 -06:00
parent eaa87cb214
commit cb296a5fe4

View file

@ -4,8 +4,29 @@ const ctx = canvas.getContext("2d");
const CANVAS_SIZE = 500; const CANVAS_SIZE = 500;
const DATA_SIZE = 200; const DATA_SIZE = 200;
let scale = 1; 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 // 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) // Color is an array of four numbers 0-255 (RGB + transparency)
function setPixel(data, x, y, color) { 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.fillStyle = "rgb(0 0 0 255)";
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
let drawScale = CANVAS_SIZE / DATA_SIZE * scale; let drawScale = CANVAS_SIZE / DATA_SIZE * scale;
let bitmap = await createImageBitmap(image);
ctx.imageSmoothingEnabled = false; ctx.imageSmoothingEnabled = false;
ctx.scale(drawScale, drawScale); ctx.scale(drawScale, drawScale);
ctx.drawImage(bitmap, 0, 0); ctx.drawImage(bitmap, offx, offy);
ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.setTransform(1, 0, 0, 1, 0, 0);
} }
canvas.addEventListener("wheel", async (e) => { canvas.addEventListener("wheel", async (e) => {
let oldScale = scale;
if (e.deltaY < 0) { if (e.deltaY < 0) {
scale += 0.1; scale += 0.1;
} else if (e.deltaY > 0) { } else if (e.deltaY > 0) {
scale -= 0.1; 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) => { canvas.addEventListener("contextmenu", (e) => {
@ -42,17 +67,41 @@ canvas.addEventListener("contextmenu", (e) => {
canvas.addEventListener("mousedown", async (e) => { canvas.addEventListener("mousedown", async (e) => {
// Left click // Left click
if (e.button == 0) { 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 x = e.clientX - canvas.getBoundingClientRect().left;
let y = e.clientY - canvas.getBoundingClientRect().top; let y = e.clientY - canvas.getBoundingClientRect().top;
let cx = Math.round(x / (CANVAS_SIZE * scale) * DATA_SIZE); let cx = Math.round(x / (CANVAS_SIZE * scale) * DATA_SIZE - offx);
let cy = Math.round(y / (CANVAS_SIZE * scale) * DATA_SIZE); let cy = Math.round(y / (CANVAS_SIZE * scale) * DATA_SIZE - offy);
setPixel(image.data, cx, cy, [255, 0, 0, 255]); console.log(cx, cy);
await draw(image); if (cx < 0 || cx > CANVAS_SIZE || cy < 0 || cy > CANVAS_SIZE) {
return;
} }
// Right click setPixel(image.data, cx, cy, [255, 0, 0, 255]);
else if (e.button == 2) { 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);
} }
}); });