Geometry & animation
The foundation packages keep exact shape data and normalized time independent from a renderer.
Geometry
@rougher-stuff/geometry owns the canonical path representation and algorithms shared by Rough.js, Perfect Arrows, and Rough Notation.
pnpm add @rougher-stuff/geometryimport { parseSvgPath, pathBounds, serializeSvgPath, transformPath } from '@rougher-stuff/geometry';
const path = parseSvgPath('m 10 10 q 20 -10 40 0');
const moved = transformPath(path, { a: 1, b: 0, c: 0, d: 1, e: 5, f: 5 });
serializeSvgPath(moved);
pathBounds(moved);Focused @rougher-stuff/geometry/path, /curve, and /polygon entry points are available. Paths use a flat canonical command stream so producers and renderers do not need an intermediate object tree.
Path metrics support deterministic drawing progress:
const halfway = pointAtLength(path, pathLength(path) / 2);
const [drawn, remaining] = splitPath(path, 0.5);See the package's geometry specification for coordinate and IR invariants.
Animation
@rougher-stuff/animation provides a framework-neutral controller for normalized progress.
pnpm add @rougher-stuff/animationimport { createAnimation } from '@rougher-stuff/animation';
const animation = createAnimation({
duration: 800,
update(progress) {
render(progress);
},
});
animation.seek(0.4).play();
await animation.finished;Controllers support play, pause, reverse, seek, cancellation, completion promises, and event subscriptions. Manual progress does not require browser layout or SVG DOM path metrics.
