106 lines
2.5 KiB
JavaScript
106 lines
2.5 KiB
JavaScript
const canvas = document.getElementById("canvas");
|
|
const ctx = canvas.getContext("2d");
|
|
|
|
const widthInput = document.getElementById("width");
|
|
const heightInput = document.getElementById("height");
|
|
const resizeButton = document.getElementById("resize");
|
|
|
|
const colorInput = document.getElementById("color");
|
|
const brushInput = document.getElementById("brush");
|
|
|
|
let color = colorInput.value;
|
|
let size = Number(brushInput.value);
|
|
let painting = false;
|
|
|
|
function resize() {
|
|
canvas.width = Number(widthInput.value);
|
|
canvas.height = Number(heightInput.value);
|
|
|
|
ctx.fillStyle = "#ffffff";
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
}
|
|
|
|
function wrap(value, size) {
|
|
return ((value % size) + size) % size;
|
|
}
|
|
|
|
function paint(x, y) {
|
|
x = wrap(x, canvas.width);
|
|
y = wrap(y, canvas.height);
|
|
|
|
const radius = size / 2;
|
|
|
|
ctx.fillStyle = color;
|
|
|
|
for (const dx of [-canvas.width, 0, canvas.width]) {
|
|
for (const dy of [-canvas.height, 0, canvas.height]) {
|
|
ctx.beginPath();
|
|
ctx.arc(x + dx, y + dy, radius, 0, Math.PI * 2);
|
|
ctx.fill();
|
|
}
|
|
}
|
|
}
|
|
|
|
function pointerPosition(event) {
|
|
const rect = canvas.getBoundingClientRect();
|
|
|
|
return {
|
|
x: (event.clientX - rect.left) * canvas.width / rect.width,
|
|
y: (event.clientY - rect.top) * canvas.height / rect.height,
|
|
};
|
|
}
|
|
|
|
canvas.addEventListener("pointerdown", event => {
|
|
painting = true;
|
|
canvas.setPointerCapture(event.pointerId);
|
|
|
|
const { x, y } = pointerPosition(event);
|
|
paint(x, y);
|
|
});
|
|
|
|
canvas.addEventListener("pointermove", event => {
|
|
if (!painting)
|
|
return;
|
|
|
|
const { x, y } = pointerPosition(event);
|
|
paint(x, y);
|
|
});
|
|
|
|
canvas.addEventListener("pointerup", event => {
|
|
painting = false;
|
|
canvas.releasePointerCapture(event.pointerId);
|
|
});
|
|
|
|
canvas.addEventListener("pointercancel", () => {
|
|
painting = false;
|
|
});
|
|
|
|
colorInput.addEventListener("input", () => {
|
|
color = colorInput.value;
|
|
});
|
|
|
|
brushInput.addEventListener("input", () => {
|
|
if (brushInput.value < 1)
|
|
brushInput.value = 1;
|
|
|
|
size = Number(brushInput.value);
|
|
});
|
|
|
|
resizeButton.addEventListener("click", resize);
|
|
|
|
resize();
|
|
|
|
const downloadButton = document.getElementById("download");
|
|
|
|
downloadButton.addEventListener("click", () => {
|
|
canvas.toBlob(blob => {
|
|
const url = URL.createObjectURL(blob);
|
|
const link = document.createElement("a");
|
|
|
|
link.href = url;
|
|
link.download = "tile_image.png";
|
|
link.click();
|
|
|
|
URL.revokeObjectURL(url);
|
|
}, "image/png");
|
|
}); |