svg沿路径运动

两个关键的API

  • getTotalLength()
    获取路径的总长度
  • getPointAtLength(distance)
    获取路径在指定长度下的某点坐标
html 复制代码
<template>
  <div style="height: 90vh; width: 90vw">
    <svg width="600px" height="400px">
      <path
        id="path"
        d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"
        stroke="black"
        fill="transparent"
      />
      <circle id="item" cx="5" cy="5" r="5"></circle>
    </svg>
  </div>
</template>
export default {
  mounted() {
    const path = document.querySelector("#path");
    const item = document.querySelector("#item");
    let len = 0;
    function move() {
      if (len > path.getTotalLength()-1) {
        len = 0;
      }
      len++;
      // 获取下一段距离的点坐标,平移过去
      const currentPoint = path.getPointAtLength(len);
      item.setAttribute("transform",`translate(${currentPoint.x-5},${currentPoint.y-5})`)
    }
    setInterval(() => {
      move();
    }, 100);
  },
};
</script>

这里要简单的介绍下svg的坐标系

svg的原点是其画布的左上角,x轴正方向向右,y轴正方向向下。
translate(x,y) 表示将物体向右移动 x 单位,向下移动 y 单位,如果想参考物体的中心点来移动,则移动距离为 (x2-x1,y2-y1)

通过不断的获取一下段距离的坐标点,改变物体的坐标实现物体的运动。效果如图下:

沿路径运动方向自动转向

  • 曲线上某一个点的运动方向为其切线的方向,我们只需要获取到该切线的夹角,并将物体旋转相同的角度即可。
  • 计算某个点的切线
js 复制代码
      // 当前点
      const currentPoint = path.getPointAtLength(len);
      // 在当前点上移动极小段距离
      const nextPoint = path.getPointAtLength(len + 0.01);
      // 该点的切线与x轴正方向的夹角      
      const angle = Math.atan2(
      nextPoint.y - currentPoint.y, 
      nextPoint.x - currentPoint.x)
      *(180 / Math.PI);

当物体的正方向不是x轴的正方向时,需要将物体旋转到x轴的正方向

如下图: 三角形的初始方向朝上,需要向右旋转90度,使其方向指向x轴的正方向

js 复制代码
    let len = 0;
    function move() {
      if (len > path.getTotalLength()-1) {
        len = 0;
      }
      len++;
      const currentPoint = path.getPointAtLength(len);
      const nextPoint = path.getPointAtLength(len + 0.01);
      // 与X轴的切线夹角
      // 在切线夹角的基础上旋转90度
      const angle =
        Math.atan2(nextPoint.y - currentPoint.y, nextPoint.x - currentPoint.x) *
        (180 / Math.PI) + 90 ;
      item.setAttribute(
        "transform",
        // 假设参考点为 (10,0)
        `translate(${currentPoint.x - 10},${currentPoint.y-0}) rotate(${angle})`
      );
      item.setAttribute("transform-origin",`${10}px ${0}px`)
    }

默认的旋转点为元素的左上角,将其修改到参考点上,得到的效果如下:

相关推荐
爱上妖精的尾巴1 天前
8-5 WPS JS宏 match、search、replace、split支持正则表达式的字符串函数
开发语言·前端·javascript·wps·jsa
为什么不问问神奇的海螺呢丶1 天前
n9e categraf redis监控配置
前端·redis·bootstrap
云飞云共享云桌面1 天前
推荐一些适合10个SolidWorks设计共享算力的服务器硬件配置
运维·服务器·前端·数据库·人工智能
刘联其1 天前
.net也可以用Electron开发跨平台的桌面程序了
前端·javascript·electron
韩曙亮1 天前
【jQuery】jQuery 选择器 ④ ( jQuery 筛选方法 | 方法分类场景 - 向下找后代、向上找祖先、同级找兄弟、范围限定查找 )
前端·javascript·jquery·jquery筛选方法
前端 贾公子1 天前
Node.js 如何处理 ES6 模块
前端·node.js·es6
pas1361 天前
42-mini-vue 实现 transform 功能
前端·javascript·vue.js
esmap1 天前
OpenClaw与ESMAP AOA定位系统融合技术分析
前端·人工智能·计算机视觉·3d·ai·js
毕设源码-钟学长1 天前
【开题答辩全过程】以 基于node.js vue的点餐系统的设计与实现为例,包含答辩的问题和答案
前端·vue.js·node.js
小白路过1 天前
记录vue-cli-service serve启动本地服务卡住问题
前端·javascript·vue.js