41 lines
1.5 KiB
TypeScript
41 lines
1.5 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import {
|
|
INK_MASK_FRAME_COUNT,
|
|
INK_MASK_FRAME_MS,
|
|
inkCoverageRadius,
|
|
inkEdgeRadius,
|
|
inkMaskFrameIndex,
|
|
} from '../src/lib/inkTransition.ts';
|
|
|
|
test('ink coverage reaches every viewport corner from the clicked origin', () => {
|
|
const viewport = { width: 1440, height: 900, originX: 1060, originY: 140 };
|
|
const radius = inkCoverageRadius(viewport);
|
|
const farthestCorner = Math.max(
|
|
Math.hypot(viewport.originX, viewport.originY),
|
|
Math.hypot(viewport.width - viewport.originX, viewport.originY),
|
|
Math.hypot(viewport.originX, viewport.height - viewport.originY),
|
|
Math.hypot(viewport.width - viewport.originX, viewport.height - viewport.originY),
|
|
);
|
|
|
|
assert.ok(radius > farthestCorner);
|
|
});
|
|
|
|
test('ink edge is organic but remains close enough to guarantee coverage', () => {
|
|
const base = 1000;
|
|
const samples = Array.from({ length: 72 }, (_, index) => inkEdgeRadius(base, index / 72 * Math.PI * 2, 1.8));
|
|
|
|
assert.ok(new Set(samples.map((value) => Math.round(value))).size > 20);
|
|
assert.ok(Math.min(...samples) > base * 0.9);
|
|
assert.ok(Math.max(...samples) < base * 1.1);
|
|
});
|
|
|
|
test('ink mask sequence matches the shipped APNG and clamps to its final frame', () => {
|
|
assert.equal(INK_MASK_FRAME_COUNT, 124);
|
|
assert.equal(inkMaskFrameIndex(0), 0);
|
|
assert.equal(inkMaskFrameIndex(INK_MASK_FRAME_MS * 10), 10);
|
|
assert.equal(inkMaskFrameIndex(60_000), 123);
|
|
assert.equal(inkMaskFrameIndex(-100), 0);
|
|
});
|