You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Framer Motion让SVG对象沿路径移动?

实现SVG对象沿Path路径移动的Framer Motion方案

核心思路

利用Framer Motion的offsetPath和offsetDistance属性控制对象沿路径移动,结合SVG原生API计算路径切线角度,让对象移动时自动对齐路径方向,实现自然的行进效果。

完整代码示例

import { motion, useAnimationFrame, useMotionValue } from "framer-motion";
import { useRef, useEffect } from "react";

export default function PathAnimation() {
  const pathRef = useRef(null);
  const totalPathLength = useMotionValue(0);
  const objectRotation = useMotionValue(0);

  // 初始化获取路径总长度
  useEffect(() => {
    if (pathRef.current) {
      totalPathLength.set(pathRef.current.getTotalLength());
    }
  }, []);

  // 实时计算对象旋转角度,对齐路径切线方向
  useAnimationFrame(() => {
    if (!pathRef.current) return;
    
    // 根据当前偏移量获取路径上的点
    const currentOffset = totalPathLength.get() * (objectRotation.get() / 100);
    const currentPoint = pathRef.current.getPointAtLength(currentOffset);
    const nextPoint = pathRef.current.getPointAtLength(currentOffset + 1);

    if (currentPoint && nextPoint) {
      // 计算切线角度并设置旋转值
      const angle = Math.atan2(nextPoint.y - currentPoint.y, nextPoint.x - currentPoint.x) * (180 / Math.PI);
      objectRotation.set(angle);
    }
  });

  return (
    <svg width="800" height="400" viewBox="0 0 800 400">
      {/* 参考路径 */}
      <path
        ref={pathRef}
        d="M50,200 C150,100 250,300 350,200 C450,100 550,300 650,200"
        fill="none"
        stroke="#ccc"
        strokeWidth="2"
      />
      {/* 沿路径移动的对象(可替换为自定义SVG图形) */}
      <motion.circle
        cx="0"
        cy="0"
        r="15"
        fill="#ff4081"
        animate={{ offsetDistance: ["0%", "100%"] }}
        transition={{
          duration: 5,
          repeat: Infinity,
          ease: "linear"
        }}
        style={{
          offsetPath: `path("${pathRef.current?.getAttribute("d")}")`,
          rotate: objectRotation,
          transformOrigin: "center"
        }}
      />
    </svg>
  );
}

关键细节说明

  • 路径绑定:通过offsetPath将对象与目标路径关联,直接复用路径的d属性值即可。
  • 路径移动控制:offsetDistance从0%到100%的动画,对应对象沿路径从起点走到终点。
  • 方向对齐:利用getPointAtLength()获取路径上相邻两点的坐标,计算切线角度后设置对象旋转,保证移动方向与路径一致。
  • 自定义对象适配:如果需要使用自定义SVG图形(比如图标、复杂路径),只需将<motion.circle>替换为<motion.g>或<motion.path>,保留style中的属性即可。
  • 动画参数调整:修改transition中的duration可以控制移动速度,移除repeat: Infinity可让动画只播放一次。

内容的提问来源于stack exchange,提问作者Sayedul Karim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 02:06:04