Blends between two other spline-sources by morph-progress — the way to make
one curve continuously interpolate into a different curve (a circle relaxing
into a square, an SVG glyph flowing into a hand-authored path).
JavaScript API:
MorphSplineSource
This is the compositing member of the spline-source family: a spline-source
supplies the curve geometry for a AbstractSpline, so it lives as the
single geometry child of a sk-spline. Unlike the leaf sources, this one
has no geometry of its own — it wraps TWO other spline-sources and produces the
per-vertex linear interpolation between them. Both children are resampled to a
matching vertex count (the larger of the two) by arc length, then positions and
widths are lerped every frame at the current morph-progress. The children may
be any spline-sources — SVG, points, GPU, trail, or even a nested
sk-morph-spline-source for recursive composition.
Key attributes. morph-progress is the blend factor in [0, 1]: 0 = the
first (source) child exactly, 1 = the second (target) child exactly, and it
is animatable, so keyframing it 0 → 1 plays the morph. The two child roles are
fixed by DOM order — the FIRST *-spline-source child is the source, the SECOND
is the target; exactly two children are required (any other count makes the
morph inert). A child that is itself a GPU source
(sk-compute-buffer-spline-source, sk-custom-wgsl-spline-source)
or a sk-trail-spline-source contributes nothing until it has CPU-side
polyline data (first readback / first accumulated points), so the morph renders
nothing until BOTH children are ready. Like every spline-source it also carries
the family's distribution / distribution-count controls: a spline-source is
itself a points-source, so a sk-cloner given one places clones along the
blended curve, and these controls choose how it is sampled into those positions.
Related. Its two children are any members of the spline-source family:
sk-svg-spline-source, sk-points-spline-source,
sk-trail-spline-source, or the GPU sources
sk-compute-buffer-spline-source / sk-custom-wgsl-spline-source.
Its host is a sk-spline, whose curve then draws with a stroke paint,
carries an sk-align-to-spline-constraint, or seeds points and fields —
and those consumers see the morph animate as morph-progress sweeps.
Serve these docs to run the live example.
WebGPU needs a secure context — open this page via grunt serve
rather than double-clicking the file. The Markup tab works from disk.
<!-- Blends between two curves and animates the blend factor 0→1→0 so the
morph plays continuously. DOM order fixes the roles: the first child (an
SVG heart) is the SOURCE, the second (a hand-authored points diamond) is
the TARGET. `morph-progress` (keyframed here) is what you read to see the
morph: at 0 the stroke is the heart, at 1 it is the diamond, and every
value between is the per-vertex interpolation of the two. -->
<sk-scene>
<sk-plain-material id="ink" base-color="#7fa8d8"></sk-plain-material>
<sk-spline>
<sk-morph-spline-source morph-progress="0">
<!-- SOURCE (morph-progress 0): an SVG heart in the ground plane. -->
<sk-svg-spline-source path="M -3,0 C -3,4 3,4 3,0 C 3,-4 -3,-4 -3,0 Z"
coordinate-space="x-z"></sk-svg-spline-source>
<!-- TARGET (morph-progress 1): a hand-authored diamond loop. -->
<sk-points-spline-source points="[[-3,0,0],[0,0,3],[3,0,0],[0,0,-3],[-3,0,0]]"
basis="linear" wrap="closed"></sk-points-spline-source>
<sk-animation duration="4000ms" iterations="Infinity"
direction="alternate" easing="ease-in-out">
<sk-keyframe offset="0" morph-progress="0"></sk-keyframe>
<sk-keyframe offset="1" morph-progress="1"></sk-keyframe>
</sk-animation>
</sk-morph-spline-source>
<sk-stroke-paint material="#ink" width="1.5"></sk-stroke-paint>
</sk-spline>
</sk-scene>
| Attribute | Type | Default | Description |
|---|---|---|---|
morph-progressanimatable |
<number> |
0 |
Initial blend factor in the range 0..1 (0 = source, 1 = target). |
distributionanimatable |
<spline-distribution> ("control-points" | "tessellated" | "arc-length-spaced") |
— | — |
distribution-count |
<number> |
— | — |