This document provides context for authors and LLMs working on the p5.plotSvg codebase.
p5.plotSvg is a JavaScript library that enables p5.js sketches to export SVG files optimized for pen plotters (like AxiDraw). It captures p5.js drawing commands and converts them to SVG paths focused on geometry only—no fills, transparency, or raster effects.
- Version: 0.1.7 (November 2025)
- Compatibility: p5.js 1.4.2 through 1.11.11
- Main file:
lib/p5.plotSvg.js(~3,300 lines)
The library is structured as an IIFE (Immediately Invoked Function Expression) that:
- Creates a
p5plotSvgnamespace object - Maintains internal state variables
- Overrides p5.js drawing functions during recording
- Stores commands in an array
- Converts commands to SVG string on export
- Exposes public API to global scope
beginRecordSvg() → overrides p5 functions → drawing commands stored in _commands[]
↓
endRecordSvg() → exportSVG() generates SVG string → restores original p5 functions
| Variable | Default | Purpose |
|---|---|---|
_bFlattenTransforms |
false |
If true, encode transforms as matrices; if false, use nested <g> groups |
_svgCoordPrecision |
4 |
Decimal places for coordinates |
_svgTransformPrecision |
6 |
Decimal places for transform values |
_svgDefaultStrokeColor |
'black' |
Default stroke color |
_svgDefaultStrokeWeight |
1 |
Default stroke weight |
_svgPointRadius |
0.25 |
Radius for point() rendered as circles |
_svgDPI |
96 |
Resolution for inch calculations |
_svgMergeNamedGroups |
true |
Merge groups with same ID |
_svgGroupByStrokeColor |
false |
Group elements by stroke color |
_bSvgExportPolylinesAsPaths |
false |
Export polylines as <path> instead of <polyline> |
| Variable | Purpose |
|---|---|
_bRecordingSvg |
Whether currently recording (can be paused) |
_bRecordingSvgBegun |
Whether recording session has started |
_commands |
Array of recorded drawing commands |
_vertexStack |
Temporary storage for vertices in beginShape/endShape |
_svgGroupLevel |
Current nesting depth for indentation |
_p5Instance |
Reference to the p5.js sketch instance |
Commands stored in _commands[] have a type field:
arc,bezier,circle,curve,ellipse,line,point,quad,rect,triangle
polyline- simple vertex-only shapespath- shapes with bezierVertex, quadraticVertex, or curveVertexpoints,lines,triangles,triangle_fan,triangle_strip,quads,quad_strip
push,pop,scale,translate,rotate,shearx,shearybeginGroup,endGroup(user-defined groups)
stroke- color change commandtext- text renderingdescription- SVG<desc>element from p5'sdescribe()
Each p5 function is overridden using this pattern:
function overrideLineFunction() {
_originalLineFunc = _p5Instance.line; // Save original
_p5Instance.line = function(x1, y1, x2, y2) {
if (_bRecordingSvg) {
let transformMatrix = captureCurrentTransformMatrix();
_commands.push({ type: 'line', x1, y1, x2, y2, transformMatrix });
}
_originalLineFunc.apply(this, arguments); // Call original
};
}Each command type has a corresponding getSvgStr*() function:
getSvgStrLine(cmd)→<line x1="..." y1="..." x2="..." y2="..."/>getSvgStrCircle(cmd)→<circle cx="..." cy="..." r="..."/>getSvgStrPoly(cmd)→<polyline>,<polygon>, or<path>- etc.
Two modes controlled by _bFlattenTransforms:
- Hierarchical (default): Transforms become nested
<g transform="...">elements - Flattened: Each element gets a
transform="matrix(...)"attribute
- Default stroke applied via CSS in
<style>block - Non-default colors add inline
style="stroke:..."to elements - Colors converted from rgba/rgb to hex format
setSvgGroupByStrokeColor(true)groups elements by color for multi-pen plotting
beginRecordSvg(p5Instance, filename)- Start recordingpauseRecordSvg(bPause)- Pause/resume recordingendRecordSvg()- Stop recording and export SVG (returns SVG string)
setSvgDocumentSize(w, h)- Override canvas dimensionssetSvgResolutionDPI(dpi)/setSvgResolutionDPCM(dpcm)setSvgDefaultStrokeColor(col)/setSvgDefaultStrokeWeight(wei)setSvgBackgroundColor(col)setSvgFlattenTransforms(bool)setSvgCoordinatePrecision(n)/setSvgTransformPrecision(n)setSvgPointRadius(r)setSvgIndent(type, amount)- UseSVG_INDENT_SPACES,SVG_INDENT_TABS, orSVG_INDENT_NONEsetSvgMergeNamedGroups(bool)setSvgGroupByStrokeColor(bool)setSvgExportPolylinesAsPaths(bool)
beginSvgGroup(name, attrs)/endSvgGroup()- Create named groups in SVG
getDefaultStrokeColor()- Get current default colorisRecordingSVG()- Check if recording is activeinjectSvgHeaderAttribute(name, value)- Add attributes to<svg>taginjectSvgDef(type, attributesObj)- Add elements to<defs>
formatNumber(val, precision)- Format numbers for SVG outputcaptureCurrentTransformMatrix()- Get current canvas transformgenerateTransformString(cmd)- Create SVG transform attributecatmullRom2bezier(crp, closed)- Convert Catmull-Rom curves to Bezierp5ArcToSvgPath(x, y, w, h, start, stop)- Convert p5 arc to SVG arc pathareColorsEqual(c1, c2)- Compare colors accounting for format differencesrgbToHex(r, g, b)- Convert RGB to hex string
- No fill support (by design—plotter-focused)
- No WEBGL mode support
textAlign()vertical modes (except BASELINE) not fully supportedcurveVertex()has minor starting orientation errorcolorMode()not supported—only CSS colors, hex, and RGB 0-255- Fonts referenced by name, not embedded
p5.plotSvg/
├── lib/
│ └── p5.plotSvg.js # Main library (~3,300 lines)
├── examples/ # Example sketches
├── images/ # README images
├── documentation.md # API documentation
├── README.md # Project overview
└── package.json # npm package config
The library exposes p5plotSvg._commands during recording, allowing addon libraries (like p5PowerStroke) to:
- Read the commands array
- Add custom commands with
attributesarrays - Inject custom SVG elements
When modifying the library, test:
- All primitive shapes with various modes (ellipseMode, rectMode, etc.)
- Transform combinations (nested push/pop with rotate/scale/translate)
- beginShape with different vertex types and shape kinds
- Stroke color changes and grouping
- Both transform modes (flattened vs. hierarchical)
- Instance mode vs. global mode usage