API Reference

Quick reference for the Pluton 2D public API: constructor, geometry, and dimensions.

Pluton2D

Constructor

const scene = new Pluton2D(svg, {
  params: { width: 240, height: 120 },
});
ParamDescription
svgSVG element to render into. Needs CSS width/height or viewBox.
options.paramsOptional flat object. Keys become reactive params. Nested objects throw at construction. Type inferred automatically.
options.viewBoxOptional coordinate space dimensions.

Flat params only. Reactivity tracks top-level mutations via Proxy. Nested objects need deep watching (not supported). Keep complex state outside scene.params, sync flat values in draw callback.

ViewBox (Coordinate Space)

Set explicit drawing coordinate system independent of pixel dimensions:

const scene = new Pluton2D(svg, {
  params: { size: 100 },
  viewBox: { width: 200, height: 300 },
});

Priority order:

  1. Constructor viewBox parameter
  2. SVG viewBox attribute
  3. SVG pixel dimensions (getBoundingClientRect)

A larger viewBox gives more room for geometry without affecting visual scale. For example, viewBox: { width: 1000, height: 1000 } provides a spacious coordinate space even if the SVG is only 500×500 pixels on screen.

Properties

PropertyDescription
paramsReactive params. Mutate properties to trigger redraws. Top-level reassignment not supported.
geometryGeometry layer. Call .group() to create groups. Groups persist across frames.
dimensionsDimensions layer. Call .group() to create groups. Groups persist across frames.

Create groups once at setup, request builders inside draw callbacks. Avoids recreating elements every frame.

Methods

const unsubscribe = scene.draw((params) => {
  // build geometry and dimensions
});

unsubscribe(); // stop this callback

scene.dispose(); // tear down everything
scene.params.width = 150; // supported
Object.assign(scene.params, { width: 200, height: 100 }); // supported
scene.params = { width: 200, height: 100 }; // throws
MethodDescription
enableFilter(bool)Enable pencil-style SVG filter. Default: false. Expensive on Safari with many paths during zoom.
setFilterIntensity(number)Set pencil displacement intensity. Default: 1.25. Higher = more wobble.
enableGrid(bool)Show/hide graph-paper background. Default: true.
enableAxes(bool)Show/hide center axes. Default: true.
enablePan(bool)Enable pan (middle-mouse or shift+click). Default: false.
enableZoom(bool)Enable wheel zoom (1×-20×). Default: false.
setViewScale(number)Scale entire view (0.1-10×) for responsive design. Doesn’t affect coordinate system or camera zoom. Smoothly interpolates.
enableFill(bool)Toggle fills globally. When enabled: uses per-path fill or default hatch. When disabled: all fills hidden.
resetCamera()Animate camera to origin with exponential easing.
addHatchFill(color, opacity?)Create 45° hatch pattern. Returns url(#id) for use in path({ fill }).
dispose()Clean up listeners, DOM, defs. Prevents memory leaks.

Engine idles when all draw callbacks unsubscribe (unless camera/input active).

const tealFill = scene.addHatchFill("#0f766e");
geom.path({ fill: tealFill }).moveToAbs(...).lineTo(...).close();

scene.setFilterIntensity(0.9);

Responsive Scaling

Scale the view programmatically for different screen sizes:

// Mobile - scale down to give geometry breathing room
if (window.innerWidth <= 640) {
  scene.setViewScale(0.7);
}

// Tablet - moderate scaling
else if (window.innerWidth <= 1024) {
  scene.setViewScale(0.85);
}

// Desktop - full scale
else {
  scene.setViewScale(1.0);
}

Key points:

  • Scales visual output only. Coordinate system unchanged
  • Zoom/pan still work normally
  • Camera state preserved (zoom level unaffected)
  • Smoothly interpolates like pan/zoom

Geometry

GeometryGroup

Create groups once, outside draw callbacks. Groups persist across frames. Request builders with path() inside draw callbacks. Engine recycles them automatically.

MethodDescription
path(options?)Request PathBuilder. Supports className, fill, stroke, fillRule. Returns chainable builder.
translate(x, y)Offset group in world space. Direct DOM write, no redraw.
scale(x, y)Scale group. Direct DOM write, no redraw.
setDrawUsage(mode)"static" commits once, "dynamic" (default) every frame. Static skips DOM writes after first commit.
clear()Remove all paths, reset state and transform.

In static mode, still call path() every frame. Engine detects unchanged geometry and skips DOM writes after first commit.

path(options) fields

OptionDescription
classNameCSS class for <path>.
fillCSS fill value (from addHatchFill() or manual). Omit for default hatch. Use "none" for stroke-only.
strokeCSS stroke value. Overrides default.
fillRule"evenodd" (default) or "nonzero". Use evenodd for cutouts, nonzero for simple fills.

PathBuilder

All methods return this for chaining. Relative commands move from the current position, absolute commands move to world coordinates.

const path = geom.path({ className: "optional-class" });

path.moveTo(dx, dy)          // relative move
path.moveToAbs(x, y)         // absolute move
path.lineTo(dx, dy)          // relative line
path.lineToAbs(x, y)         // absolute line
path.cubicTo(c1dx, c1dy, c2dx, c2dy, dx, dy)         // relative cubic Bezier
path.cubicToAbs(c1x, c1y, c2x, c2y, x, y)            // absolute cubic Bezier
path.smoothCubicTo(c2dx, c2dy, dx, dy)               // relative smooth cubic
path.smoothCubicToAbs(c2x, c2y, x, y)                // absolute smooth cubic
path.quadTo(c1dx, c1dy, dx, dy)                      // relative quadratic Bezier
path.quadToAbs(c1x, c1y, x, y)                       // absolute quadratic Bezier
path.smoothQuadTo(dx, dy)                            // relative smooth quadratic
path.smoothQuadToAbs(x, y)                           // absolute smooth quadratic
path.arcTo(dx, dy, r, clockwise?, largeArc?)    // relative arc
path.arcToAbs(x, y, r, clockwise?, largeArc?)   // absolute arc
path.close()                 // close path
path.reset()                 // clear commands

Curve types

Command familyWhen to use
cubicTo / cubicToAbs (C/c)Most control for organic shapes. You get two control points (entry and exit handles), which gives you full control over the curve shape.
smoothCubicTo / smoothCubicToAbs (S/s)Continue a cubic curve smoothly. The first handle is inferred by mirroring the previous segment’s exit handle. Useful for connected S-curves.
quadTo / quadToAbs (Q/q)Simpler curves with one control point. Lighter weight than cubic, good for rounded corners and simple arcs.
smoothQuadTo / smoothQuadToAbs (T/t)Continue a quadratic curve smoothly with inferred control point. Useful for smooth wave-like forms.

Smooth commands (S/s, T/t) depend on the previous curve segment. If no compatible segment exists (like after a line or move), SVG treats the inferred control point as the current point, which produces a sharp corner.

ParamDescription
clockwiseArc sweep direction in visual space (after Y-flip). Default: false. Pass true to sweep clockwise on screen.
largeArcWhether the arc spans more than 180 degrees. Default: false. Use true for major arcs.
r ≤ 0Falls back to straight line, creating a sharp corner instead of an arc.

Dimensions

DimensionsGroup

Create groups once, outside draw callbacks. Same pattern as geometry groups.

Methods: translate(x, y), setDrawUsage(mode), clear(), dimension(options?). Clear resets translation to origin.

DimensionsBuilder: Positioning

const dim = dims.dimension({ className: "optional-class" });

dim.moveTo(dx, dy); // relative move
dim.moveToAbs(x, y); // absolute move
dim.lineTo(dx, dy); // relative line
dim.lineToAbs(x, y); // absolute line

Relative moves from current position, absolute moves to world coordinates. Use for dimension lines and leaders.

DimensionsBuilder: Primitives

Angles in radians. 0 points right, π/2 points up.

dim.arc(r, startAngle, endAngle)     // arc centered at current position
dim.arrow(angleRad, size?)           // open arrow (default size: 8)
dim.arrowFilled(angleRad, size?)     // filled arrow (default size: 8)
dim.tick(angleRad, size?)            // architectural tick (default size: 15)
dim.centerMark(size?)                // crosshair with center dot (default size: 10)
dim.close()                          // close path
PrimitiveNotes
arcArc from startAngle to endAngle around current position. Direction inferred from angle order.
arrowOpen V-arrow. Tip at current position, wings extend back. Classic style.
arrowFilledFilled triangle arrow on separate path layer. Modern style.
tickArchitectural tick: crossed lines rotated by angleRad.
centerMarkCrosshair with filled center dot.

DimensionsBuilder: Text

dim.textAt(dx, dy, text, align?, className?)
dim.textAtAbs(x, y, text, align?, className?)

align: "start" | "middle" | "end" (default: "middle"). Controls text anchor. className: Optional CSS class for <text>.

Text rendered in world space (Y-up). Engine transforms it to appear upright on screen.