Skip to content
Docs
Open Promoeyes
paths

paths

Path primitives — every way to write `<path d="…">`, then every way to MOVE one. Three matched haze lobes (hz0..hz2) ride every scene so `transition=match-move` carries the backdrop across each cut.

Read the rig's notes
PART ONE · the grammar (1-8). Each scene is a static pose: the outline does
the work, not keyframes.

  1. lines        — M / L / H / V / Z: a polygon is just a path with no curves
  2. cubics       — C, and S reusing the previous control point by reflection
  3. quadratics   — Q, and T reflecting the previous control the same way
  4. arcs         — A: endpoint-parameterised ellipse arcs, flags and all
  5. holes        — extra sub-paths become holes; a ring is two circles
  6. relative     — lowercase commands, proven against their absolute twin
  7. depth+bevel  — one outline, four extrusions
  8. curve_segments — one outline, four tessellations

PART TWO · the motion (9-18). Every animation the engine can put on a path,
one per scene:

  9. keyframes    — `<properties>` channels on the node: position, rotation,
                    scale, opacity, material color. The `d` never changes.
 10-11. match-move — a shared `match` key carries a shape across the cut: the
                    pose/scale/colour interpolate and the two OUTLINES
                    crossfade inside that shared travel (silhouette swap).
                    ONE chain of three keys (mv-a/b/c) runs 9 → 14, so every
                    gap in this half is a real pairing, not a dissolve.
 12-14. particles  — the same three keys plus `morph="particles"`: the outgoing shape
                    is sampled into a swarm that flies bézier paths and
                    converges onto the incoming one. Scene 13 shows the
                    morph-count / spread / colour / size / blend / stagger knobs.
 15. point morph   — the ONLY true outline interpolation: `<path3d>` sweeps a
                    cross-section along a `d` and takes a KEYFRAMED `d`, so
                    the anchors and bézier handles themselves lerp. Every
                    keyframe must share one command structure.
 16. through       — fly INTO a path's silhouette; its shape becomes the
                    window onto the next scene (a ring aims at its own ink,
                    not its hole).
 17-18. emerge     — the mirror: pull back OUT of a shape of the NEXT scene,
                    which the outgoing scene collapses into.

Not shown here because it is not a path primitive: `<icon>` point-morphs two
icon-set outlines with different command counts (path2curve normalises them)
— see promos/helpers/icon-morph-demo.

`d` is the ONLY outline spelling for an extruded path, and it is read in a
Y-UP space — +y is up on screen, unlike an SVG document. Everything else is
identical to SVG path data: M/L/H/V/C/S/Q/T/A/Z, absolute and relative, with
implicit repeated coordinate pairs after a command letter. Nothing is
flattened on the way in — curves reach the runtime as real curve segments and
`curve_segments` decides how finely they tessellate (scene 8).

Each shape is a `<primitive>` whose `<path>` child IS its geometry:
    primitive#hex(position="0 0.35 0" rotation="0 -22 0")
      path(d="M 0 0.8 L -0.693 0.4 … Z" depth=0.22 bevel=0.035)
      material(ref=standard color=#60a5fa metalness=0.3 roughness=0.35)
Outlines are authored around the origin so `position` is the visual centre —
hand-authored geometry is never auto-centred (pass `center=true` to opt in).

Preview: /packages/runtime/index.html?project=promos/primitives/shapes/paths.promo
Topic
shapes
Scenes
18
Kind
reference rig
//
    Path primitives — every way to write `<path d="…">`, then every way to MOVE
    one. Three matched haze lobes (hz0..hz2) ride every scene so
    `transition=match-move` carries the backdrop across each cut.

    PART ONE · the grammar (1-8). Each scene is a static pose: the outline does
    the work, not keyframes.

      1. lines        — M / L / H / V / Z: a polygon is just a path with no curves
      2. cubics       — C, and S reusing the previous control point by reflection
      3. quadratics   — Q, and T reflecting the previous control the same way
      4. arcs         — A: endpoint-parameterised ellipse arcs, flags and all
      5. holes        — extra sub-paths become holes; a ring is two circles
      6. relative     — lowercase commands, proven against their absolute twin
      7. depth+bevel  — one outline, four extrusions
      8. curve_segments — one outline, four tessellations

    PART TWO · the motion (9-18). Every animation the engine can put on a path,
    one per scene:

      9. keyframes    — `<properties>` channels on the node: position, rotation,
                        scale, opacity, material color. The `d` never changes.
     10-11. match-move — a shared `match` key carries a shape across the cut: the
                        pose/scale/colour interpolate and the two OUTLINES
                        crossfade inside that shared travel (silhouette swap).
                        ONE chain of three keys (mv-a/b/c) runs 9 → 14, so every
                        gap in this half is a real pairing, not a dissolve.
     12-14. particles  — the same three keys plus `morph="particles"`: the outgoing shape
                        is sampled into a swarm that flies bézier paths and
                        converges onto the incoming one. Scene 13 shows the
                        morph-count / spread / colour / size / blend / stagger knobs.
     15. point morph   — the ONLY true outline interpolation: `<path3d>` sweeps a
                        cross-section along a `d` and takes a KEYFRAMED `d`, so
                        the anchors and bézier handles themselves lerp. Every
                        keyframe must share one command structure.
     16. through       — fly INTO a path's silhouette; its shape becomes the
                        window onto the next scene (a ring aims at its own ink,
                        not its hole).
     17-18. emerge     — the mirror: pull back OUT of a shape of the NEXT scene,
                        which the outgoing scene collapses into.

    Not shown here because it is not a path primitive: `<icon>` point-morphs two
    icon-set outlines with different command counts (path2curve normalises them)
    — see promos/helpers/icon-morph-demo.

    `d` is the ONLY outline spelling for an extruded path, and it is read in a
    Y-UP space — +y is up on screen, unlike an SVG document. Everything else is
    identical to SVG path data: M/L/H/V/C/S/Q/T/A/Z, absolute and relative, with
    implicit repeated coordinate pairs after a command letter. Nothing is
    flattened on the way in — curves reach the runtime as real curve segments and
    `curve_segments` decides how finely they tessellate (scene 8).

    Each shape is a `<primitive>` whose `<path>` child IS its geometry:
        primitive#hex(position="0 0.35 0" rotation="0 -22 0")
          path(d="M 0 0.8 L -0.693 0.4 … Z" depth=0.22 bevel=0.035)
          material(ref=standard color=#60a5fa metalness=0.3 roughness=0.35)
    Outlines are authored around the origin so `position` is the visual centre —
    hand-authored geometry is never auto-centred (pass `center=true` to opt in).

    Preview: /packages/runtime/index.html?project=promos/primitives/shapes/paths.promo
promo#paths
  // =======================================================================
  // SCENE 01 · LINES — M / L / H / V / Z
  // =======================================================================
  scene#s01-lines(duration=4 transition=match-move