SVG 变形不平滑变形 - 动漫 js
SVG morph not morphing smoothly - anime js
我正在尝试使用 Anime JS 创建一个简单的 SVG 变形,但 SVG 过渡不平滑,如下图所示,它会跳跃。有谁知道为什么会这样?
const SVG_PATHS = [
{ value: "M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" },
{ value: "M1920,466H0V359s159-60,960-73S1920,0,1920,0Z" }
];
const MORPH_SVG = anime({
targets: ".path",
d: [
SVG_PATHS[1],
SVG_PATHS[0]
],
easing: "linear",
duration: 5000,
loop: true
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 349" class="svg_curve">
<path style="fill: #000;" d="M1920, 349H0V242s468-52.44, 1160-73.33S1920, 0, 1920, 0Z" class="path"/>
</svg>
使用 SVG_PATHS[0] 作为路径的值
const SVG_PATHS = [
{ value: "M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" },
{ value: "M1920,466H0V359s159-60,960-73S1920,0,1920,0Z" }
];
const MORPH_SVG = anime({
targets: ".path",
d: [
SVG_PATHS[1],
SVG_PATHS[0]
],
easing: "linear",
duration: 5000,
loop: true
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 349" class="svg_curve">
<path style="fill: #000;" d="M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" class="path"/>
</svg>
在我的回答中,我想给出实现平滑动画的一般建议,并结合问题作者的具体示例进行考虑。
使用d
属性实现平滑动画路径变化的主要条件是:
- 节点数相同
- 节点类型(A;C;Q)的精确匹配,分别针对路径初始和最终位置中的每个点
可以通过不同的方式满足这些条件,但最好在矢量编辑器中进行。
下图是矢量编辑器中的初始路径,需要转换为最终路径,注意条件相同,节点数相同。
红色箭头显示需要移动的节点。
- 要移动选定的锚点,您必须同时单击以标记它们
持有 shift
- 然后按住Ctrl键,把光标放在选中的点上
并将整个曲线移动到动画的最终位置。
- 在矢量编辑器中以
* .svg
格式保存文件并复制
最后的公式path
动画实现
现在我们有了公式的初始路径和最终路径。要实现属性 d
路径的动画,请使用命令 SMIL
<animate attributeName="d" values="`begin path`;`final path`" .... />
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 349" class="svg_curve">
<path style="fill: #000;" d="M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" class="path">
<animate attributeName="d"
values="
M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z;
M1920,466H0V359s159-60,960-73S1920,0,1920,0Z"
dur="5s"
fill="freeze"
/>
</path>
</svg>
要循环播放动画,请添加值属性 begin path
:
<animate attributeName="d" values="`begin path`;`final path`;begin path" .... />
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 349" class="svg_curve">
<path style="fill: #000;" d="M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" class="path">
<animate attributeName="d"
values="
M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z;
M1920,466H0V359s159-60,960-73S1920,0,1920,0Z;
M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z"
dur="5s"
fill="freeze"
repeatCount="indefinite"
/>
</path>
</svg>
更新
绕过精确匹配节点数量和类型的限制允许插件kute-svg.js
插件使用example
我正在尝试使用 Anime JS 创建一个简单的 SVG 变形,但 SVG 过渡不平滑,如下图所示,它会跳跃。有谁知道为什么会这样?
const SVG_PATHS = [
{ value: "M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" },
{ value: "M1920,466H0V359s159-60,960-73S1920,0,1920,0Z" }
];
const MORPH_SVG = anime({
targets: ".path",
d: [
SVG_PATHS[1],
SVG_PATHS[0]
],
easing: "linear",
duration: 5000,
loop: true
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 349" class="svg_curve">
<path style="fill: #000;" d="M1920, 349H0V242s468-52.44, 1160-73.33S1920, 0, 1920, 0Z" class="path"/>
</svg>
使用 SVG_PATHS[0] 作为路径的值
const SVG_PATHS = [
{ value: "M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" },
{ value: "M1920,466H0V359s159-60,960-73S1920,0,1920,0Z" }
];
const MORPH_SVG = anime({
targets: ".path",
d: [
SVG_PATHS[1],
SVG_PATHS[0]
],
easing: "linear",
duration: 5000,
loop: true
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 349" class="svg_curve">
<path style="fill: #000;" d="M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" class="path"/>
</svg>
在我的回答中,我想给出实现平滑动画的一般建议,并结合问题作者的具体示例进行考虑。
使用d
属性实现平滑动画路径变化的主要条件是:
- 节点数相同
- 节点类型(A;C;Q)的精确匹配,分别针对路径初始和最终位置中的每个点
可以通过不同的方式满足这些条件,但最好在矢量编辑器中进行。
下图是矢量编辑器中的初始路径,需要转换为最终路径,注意条件相同,节点数相同。
红色箭头显示需要移动的节点。
- 要移动选定的锚点,您必须同时单击以标记它们 持有 shift
- 然后按住Ctrl键,把光标放在选中的点上 并将整个曲线移动到动画的最终位置。
- 在矢量编辑器中以
* .svg
格式保存文件并复制 最后的公式path
动画实现
现在我们有了公式的初始路径和最终路径。要实现属性 d
路径的动画,请使用命令 SMIL
<animate attributeName="d" values="`begin path`;`final path`" .... />
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 349" class="svg_curve">
<path style="fill: #000;" d="M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" class="path">
<animate attributeName="d"
values="
M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z;
M1920,466H0V359s159-60,960-73S1920,0,1920,0Z"
dur="5s"
fill="freeze"
/>
</path>
</svg>
要循环播放动画,请添加值属性 begin path
:
<animate attributeName="d" values="`begin path`;`final path`;begin path" .... />
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.0.2/anime.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 349" class="svg_curve">
<path style="fill: #000;" d="M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z" class="path">
<animate attributeName="d"
values="
M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z;
M1920,466H0V359s159-60,960-73S1920,0,1920,0Z;
M1920,349H0V242s468-52.44,960-73.33S1920,0,1920,0Z"
dur="5s"
fill="freeze"
repeatCount="indefinite"
/>
</path>
</svg>
更新
绕过精确匹配节点数量和类型的限制允许插件kute-svg.js
插件使用example