Paperclip Rig

Rig the outline. Pack the sheet.

Drag a Bezier node, slide the tolerance, and watch a traced contour lose most of its points while the silhouette holds. Then paint a sprite, swap its palette and pack the frames into the smallest sheet that fits.

A small open source workbench for vector paths, pixel sprites and texture atlases, with eighteen sample assets. One file of engine code, no dependencies.

Ginkgo leaf, Blade layer Drag a node or a handle. Arrow keys nudge the focused point, Shift moves by five.

Fewer nodes, same silhouette

The editor flattens your curve into a dense trace, runs Ramer-Douglas-Peucker at the tolerance you pick, then refits smooth cubics through the points it kept. Sharp corners stay sharp. Every figure below is recomputed as you drag.

Live view of the plate Edit on the plate
Handles
0.60 units
2
Trace points
0
Points kept
0
Trace as polyline
0 B
Simplified path
0 B
Size change
0%
Worst drift
0
Editable nodes
0
Path length
0
Bounding box
0
Peak curvature
0

A walk cycle on a five tone palette

Sprites store tones, not colours. Pick a palette and the engine ranks its colours by OKLab lightness, so the darkest tone always lands on the darkest colour. Onion skin shows the neighbouring frames in blue and red while you paint.

Traveler walk cycle, frame 1 of 4, 16 by 16

6 fps
Canvas
Tone to paint with
Tool

Pack it tight

MaxRects with the Best Short Side Fit rule searches power of two sheets from smallest to largest and keeps the first one that holds every frame. Hatched areas are wasted pixels, and the page checks the result for overlaps before it shows a number.

No atlas yet
0.0%

of the sheet is sprite pixels

Sheet size
0
Frames packed
0
Wasted pixels
0
Overlap check
pending
Frames
32
48 px
7
2 px
1 px

Eighteen sample assets

Ten layered vector pieces and eight pixel sprites. They are plain files you can use, and each one opens in its bench. They were authored in code, so treat them as fixtures and starting points rather than finished art.

Vector, layered SVG

Pixel, indexed sprites

What is real here

  • The engine is one dependency free file. It runs in the browser and under Node, and every number on this page comes from it.
  • Simplification is Ramer-Douglas-Peucker on a dense trace of your own curve, followed by a smooth cubic refit. The drift readout is the measured worst distance between the trace and the result.
  • Packing uses MaxRects with Best Short Side Fit. Descriptor layouts follow the TexturePacker and Phaser JSON shapes, and the Godot list is our own small schema. They have not been loaded into those tools here.
  • Palette swaps rank colours by OKLab lightness, and the quantiser can use OKLab or CIE Lab distance.