47 lines
1.4 KiB
JavaScript
47 lines
1.4 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
const root = window.PixelIslandModules ||= {};
|
|
|
|
function clonePixels(pixels) {
|
|
return Array.isArray(pixels) ? [...pixels] : [];
|
|
}
|
|
|
|
function floodFill(sourcePixels, width, x, y, colorCode, height = width) {
|
|
const w = Math.max(1, Math.round(Number(width) || 1));
|
|
const h = Math.max(1, Math.round(Number(height) || w));
|
|
const pixels = clonePixels(sourcePixels);
|
|
const target = pixels[y * w + x] || null;
|
|
const replacement = colorCode || null;
|
|
if (target === replacement) return { pixels, changed: false, count: 0, cells: [] };
|
|
|
|
const stack = [[x, y]];
|
|
const cells = [];
|
|
while (stack.length) {
|
|
const [cx, cy] = stack.pop();
|
|
if (cx < 0 || cy < 0 || cx >= w || cy >= h) continue;
|
|
const index = cy * w + cx;
|
|
if ((pixels[index] || null) !== target) continue;
|
|
pixels[index] = replacement;
|
|
cells.push({ x: cx, y: cy });
|
|
stack.push([cx + 1, cy], [cx - 1, cy], [cx, cy + 1], [cx, cy - 1]);
|
|
}
|
|
return { pixels, changed: cells.length > 0, count: cells.length, cells };
|
|
}
|
|
|
|
function pickColor(sourcePixels, size, x, y) {
|
|
if (!Array.isArray(sourcePixels)) return null;
|
|
if (x < 0 || y < 0 || x >= size || y >= size) return null;
|
|
return sourcePixels[y * size + x] || null;
|
|
}
|
|
|
|
root.EditorActions = {
|
|
clonePixels,
|
|
floodFill,
|
|
pickColor,
|
|
apply(snapshot, pushHistory, mutate) {
|
|
pushHistory(snapshot());
|
|
mutate();
|
|
}
|
|
};
|
|
})();
|