Cookbook snippet · tier 2
SVG 路徑變形
在兩個 SVG path d 屬性之間內插,做出平滑的形狀過場。
Live example
transition: d 平滑插值需要兩個條件:
- 兩個
d的命令數一致(M / C / L / Z 數量與順序相同)。 - 每個 segment 的端點在兩個
d裡 *同位置*。
本檔三個 shape 共用 4 個軸向端點,只動 cubic 控制點 → 圓 → soft → 端點重合(diamond)。
完整食譜 (HTML + JS · 複製改寫用)
Interpolate between two SVG
path dattributes for smooth shape transitions.
When to use
- Smooth transition between two architecture states
- Animated graph layout (force-directed settle)
- Morphing one curve into another in a chart (before/after view)
Complete snippet (paste-and-tweak)
<figure class="vg-w-morph-EXAMPLE">
<svg viewBox="0 0 200 100">
<path id="vg-w-morph-EXAMPLE-p" d="M 10 50 Q 100 10 190 50" fill="none" stroke="var(--accent)" stroke-width="2" />
</svg>
<button id="vg-w-morph-EXAMPLE-toggle">morph</button>
<script>
(function () {
const root = document.querySelector('.vg-w-morph-EXAMPLE');
const path = root.querySelector('#vg-w-morph-EXAMPLE-p');
const btn = root.querySelector('#vg-w-morph-EXAMPLE-toggle');
const A = 'M 10 50 Q 100 10 190 50';
const B = 'M 10 50 Q 100 90 190 50';
let toB = true;
btn.addEventListener('click', () => {
path.animate(
[{ d: `path('${toB ? A : B}')` }, { d: `path('${toB ? B : A}')` }],
{ duration: 600, easing: 'ease-in-out', fill: 'forwards' }
);
toB = !toB;
});
})();
</script>
</figure>
Gotchas
- Path command compatibility: morph only works smoothly when both paths have the same command sequence (same number of M/L/Q/C segments). If they differ, browsers fall back to a jumpy linear interpolation.
path('...')CSS syntax is needed inside WAAPI keyframes for thedattribute. Without it, the browser treatsdas a generic string and animates per-character (broken).- Falling back to manual interpolation: if browsers don't morph cleanly, parse both paths into segments and lerp coordinates in rAF — more code but bulletproof.