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属性实现平滑动画路径变化的主要条件是:

  1. 节点数相同
  2. 节点类型(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