Files
moteva/frontend/tests/colorBoundaryCrop.test.mjs
T
root b363dcf888 feat(canvas): add leafer GPU renderer and interactive color-boundary crop tool
Introduce a leafer-ui canvas layer that mirrors rendered nodes and drives
viewport, node-drag, and alignment-guide updates imperatively, committing
React state on idle via startTransition to keep pan/zoom/drag at 60fps. Wire
the imperative viewport through wheel zoom, zoom-to, fit-view, and panning.

Add a dedicated crop tool: click a node to auto-detect a color-boundary crop
region or drag to preselect one, previewed with an on-canvas draft overlay
before entering the crop editor. Route uploads through renderContent so the
transparent WebP texture feeds the fast display path. Add node --test
coverage for the leafer renderer and color-boundary detection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 20:46:31 +08:00

62 lines
1.9 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import { findColorBoundaryCrop, mapColorBoundaryCropToLimit } from "../src/ui/pages/CanvasWorkspace/canvas/colorBoundaryCrop.ts";
function imageFixture(width, height, background, region) {
const data = new Uint8ClampedArray(width * height * 4);
for (let y = 0; y < height; y += 1) {
for (let x = 0; x < width; x += 1) {
const offset = (y * width + x) * 4;
const inside = x >= region.left && x < region.right && y >= region.top && y < region.bottom;
const color = inside ? region.color(x, y) : background;
data[offset] = color[0];
data[offset + 1] = color[1];
data[offset + 2] = color[2];
data[offset + 3] = color[3] ?? 255;
}
}
return { width, height, data };
}
test("finds the connected color-bounded region around a crop click", () => {
const image = imageFixture(12, 10, [235, 235, 235, 255], {
left: 3,
top: 2,
right: 9,
bottom: 7,
color: (x, y) => [64 + x, 72 + y, 80, 255]
});
assert.deepEqual(findColorBoundaryCrop(image, { x: 0.5, y: 0.4 }), {
x: 0.25,
y: 0.2,
width: 0.5,
height: 0.5
});
});
test("uses the full analyzable area when no color boundary encloses the click", () => {
const image = imageFixture(8, 6, [250, 250, 250, 255], {
left: 0,
top: 0,
right: 0,
bottom: 0,
color: () => [0, 0, 0, 255]
});
assert.deepEqual(findColorBoundaryCrop(image, { x: 0.5, y: 0.5 }), { x: 0, y: 0, width: 1, height: 1 });
});
test("never expands automatic selection beyond the currently visible crop limit", () => {
const visibleLimit = { x: 0.18, y: 0.12, width: 0.64, height: 0.7 };
assert.deepEqual(mapColorBoundaryCropToLimit({ x: 0, y: 0, width: 1, height: 1 }, visibleLimit), visibleLimit);
assert.deepEqual(mapColorBoundaryCropToLimit({ x: 0.25, y: 0.2, width: 0.5, height: 0.4 }, visibleLimit), {
x: 0.34,
y: 0.26,
width: 0.32,
height: 0.28
});
});