Path
Responsibility
Path is the freeform vector primitive. It contains one or more named contours, and each contour contains an explicit start point followed by line, quadratic, cubic or arc segments. A path can be filled, stroked, or both.
Complete path layer
{
"id": "ribbon",
"type": "path",
"parentLayerId": null,
"order": 0,
"frame": { "width": 720, "height": 420 },
"transform": {
"translate": { "x": 360, "y": 240, "z": 0 },
"rotate": { "x": 0, "y": 0, "z": -4 },
"scale": { "x": 1, "y": 1, "z": 1 },
"anchor": { "x": 360, "y": 210, "z": 0 },
"skew": { "x": 0, "y": 0 }
},
"timing": { "start": 0, "duration": 5000 },
"payload": {
"fillRule": "nonzero",
"pathLength": 1000,
"contours": [{
"id": "main-ribbon",
"start": { "x": 40, "y": 300 },
"closed": true,
"segments": [
{
"kind": "cubic",
"control1": { "x": 180, "y": 40 },
"control2": { "x": 420, "y": 40 },
"to": { "x": 680, "y": 250 }
},
{
"kind": "quadratic",
"control": { "x": 430, "y": 360 },
"to": { "x": 40, "y": 300 }
}
]
}]
},
"style": {
"fill": "#6257FF",
"fillOpacity": 0.9,
"stroke": "#D8FFF7",
"strokeWidth": 5,
"strokeOpacity": 1,
"strokeJoin": "round",
"strokeCap": "round"
}
}
Contours and segments
| Segment | Required fields | Meaning |
|---|---|---|
line | to | Straight line from the current point |
quadratic | control, to | One control point |
cubic | control1, control2, to | Two control points |
arc | radii, rotation, largeArc, sweep, to | Elliptical arc using SVG arc flags |
Every contour requires id, start, at least one segments entry and closed. Segment to points become the next current point. A closed contour implicitly connects its final point back to start; an open contour remains open for stroke rendering.
{
"contours": [{
"id": "mixed-segments",
"start": { "x": 80, "y": 180 },
"closed": false,
"segments": [
{ "kind": "line", "to": { "x": 180, "y": 80 } },
{ "kind": "quadratic", "control": { "x": 260, "y": 20 }, "to": { "x": 360, "y": 100 } },
{ "kind": "cubic", "control1": { "x": 440, "y": 180 }, "control2": { "x": 520, "y": 180 }, "to": { "x": 620, "y": 80 } },
{ "kind": "arc", "radii": { "x": 60, "y": 40 }, "rotation": 0, "largeArc": false, "sweep": true, "to": { "x": 700, "y": 160 } }
]
}]
}
Fill rules and holes
nonzero and evenodd decide how multiple closed contours produce filled regions. Use evenodd for the common “outer contour plus inner hole” case:
{
"payload": {
"fillRule": "evenodd",
"contours": [
{
"id": "outer",
"start": { "x": 40, "y": 40 },
"closed": true,
"segments": [
{ "kind": "line", "to": { "x": 360, "y": 40 } },
{ "kind": "line", "to": { "x": 360, "y": 260 } },
{ "kind": "line", "to": { "x": 40, "y": 260 } }
]
},
{
"id": "hole",
"start": { "x": 120, "y": 100 },
"closed": true,
"segments": [
{ "kind": "line", "to": { "x": 280, "y": 100 } },
{ "kind": "line", "to": { "x": 280, "y": 200 } },
{ "kind": "line", "to": { "x": 120, "y": 200 } }
]
}
]
}
}
Stroke and drawing controls
Path style uses the same paint model as Shape:
| Field | Meaning |
|---|---|
fill, fillOpacity | Interior paint and alpha |
stroke, strokeWidth, strokeOpacity | Outline paint, width and alpha |
strokeJoin | miter, bevel or round |
strokeCap | butt, square or round |
strokeDash | Dash array and offset |
paintOrder | Fill, stroke and marker ordering |
vectorEffect | none or non-scaling-stroke |
markerStart/Mid/End | References to root marker definitions |
pathLength is an optional calibration length used by dash and motion semantics. It does not alter the geometry coordinates.
Morphing between paths
A path can carry a compatible target contour set and a normalized morph.progress value:
{
"payload": {
"contours": [{
"id": "start",
"start": { "x": 80, "y": 80 },
"closed": true,
"segments": [
{ "kind": "line", "to": { "x": 280, "y": 80 } },
{ "kind": "line", "to": { "x": 180, "y": 260 } }
]
}],
"morph": {
"progress": 0.5,
"targetContours": [{
"id": "target",
"start": { "x": 80, "y": 160 },
"closed": true,
"segments": [
{ "kind": "line", "to": { "x": 280, "y": 160 } },
{ "kind": "line", "to": { "x": 180, "y": 40 } }
]
}]
}
}
}
Morphing requires matching contour and segment structure. If the topology differs, author a separate path or use a layer transition instead of expecting the compiler to invent correspondence.