rkgk/static/painter.js

77 lines
2.7 KiB
JavaScript

import { listen } from "rkgk/framework.js";
function numChunksInRectangle(rect, chunkSize) {
let leftChunk = Math.floor(rect.left / chunkSize);
let topChunk = Math.floor(rect.top / chunkSize);
let rightChunk = Math.ceil(rect.right / chunkSize);
let bottomChunk = Math.ceil(rect.bottom / chunkSize);
let numX = rightChunk - leftChunk;
let numY = bottomChunk - topChunk;
return numX * numY;
}
function* chunksInRectangle(rect, chunkSize) {
let leftChunk = Math.floor(rect.left / chunkSize);
let topChunk = Math.floor(rect.top / chunkSize);
let rightChunk = Math.ceil(rect.right / chunkSize);
let bottomChunk = Math.ceil(rect.bottom / chunkSize);
for (let chunkY = topChunk; chunkY < bottomChunk; ++chunkY) {
for (let chunkX = leftChunk; chunkX < rightChunk; ++chunkX) {
yield [chunkX, chunkY];
}
}
}
export function renderToChunksInArea(layer, renderArea, renderToPixmap) {
for (let [chunkX, chunkY] of chunksInRectangle(renderArea, layer.chunkSize)) {
let chunk = layer.getOrCreateChunk(chunkX, chunkY);
if (chunk == null) continue;
let translationX = -chunkX * layer.chunkSize;
let translationY = -chunkY * layer.chunkSize;
let result = renderToPixmap(chunk.pixmap, translationX, translationY);
chunk.markModified();
if (result.status != "ok") return result;
}
return { status: "ok" };
}
export function dotterRenderArea(wall, dotter) {
let halfPaintArea = wall.paintArea / 2;
return {
left: dotter.toX - halfPaintArea,
top: dotter.toY - halfPaintArea,
right: dotter.toX + halfPaintArea,
bottom: dotter.toY + halfPaintArea,
};
}
export function selfController(interactionQueue, wall, layer, event) {
let renderArea = null;
return {
async runScribble(renderToPixmap) {
interactionQueue.push({ kind: "scribble" });
if (renderArea != null) {
let numChunksToRender = numChunksInRectangle(renderArea, layer.chunkSize);
let result = renderToChunksInArea(layer, renderArea, renderToPixmap);
return result;
} else {
console.debug("render area is empty, nothing will be rendered");
}
return { status: "ok" };
},
async runDotter() {
let dotter = await event.continueAsDotter();
interactionQueue.push({
kind: "dotter",
from: { x: dotter.fromX, y: dotter.fromY },
to: { x: dotter.toX, y: dotter.toY },
num: dotter.num,
});
renderArea = dotterRenderArea(wall, dotter);
return dotter;
},
};
}