形状形变 morph:path d 插值
两条 path 之间的平滑形变,本质仍是插值——只不过插的不是一个数,而是 d
属性里的一长串坐标。前提很硬:两条 path 的命令结构必须相同(命令类型与数量一一对应)。
满足这点后,把两条 path 的数值参数逐位线性插值,再拼回 d 字符串
setAttribute 到同一个 <path>,形状就会从一个连续地长成另一个。
本页第一部分的四个形状(circle / square / star / heart)都用同样数量的 C 曲线写出,顶点天然一一对应,
因此可以直接互相 morph;第二部分再处理命令结构不同的通用情形(重采样 + 对齐)。
目标 heart
进度 —
命令数 —
命令结构不同的形状之间(三角形 3 段直线、十字 12 段、blob 几段曲线),逐位插值就失效了。
通用做法是重采样:用 getTotalLength() / getPointAtLength()
把每个形状按弧长均匀采成同样多的点,任意 path 都化成等长点集,即可逐点插值。再做一次
旋转对齐(循环移位,让两组点的起点与走向最接近),避免 morph 时整体拧成麻花。
关掉「旋转对齐」就能看到不对齐时的扭曲。
目标 cross
采样点 —
对齐移位 —
d 就退化成一个等长数字数组,与数字插值
完全同构,只是维度从 1 变成几十。本页的四个形状刻意都写成「1 个 M + 8 个 C」,数组长度恒为 50,
所以任意两者之间都能直接 morph。
@vega/anim — d 数组逐位插值
若只想画出单条路径本身、或让物体沿路径行进,见SVG 路径动画;
morph 把整段 d 当作高维向量来插,与基础的插值同源,
区别只在于此处需要一个「path 插值器」(逐位混合数字 + 拼回 d),而非单值的 mix。