使用贝塞尔曲线实现元素沿曲线运动

业务场景

最近业务中遇到了一个点赞需求,就很常见的那种直播点赞,设计上要求点赞气泡随机沿着弧线运动路径向上飞,简单点可以把关键帧动画硬编码,但是我感觉那么做不是很完美,就想到了用贝塞尔曲线来实现这个功能

贝塞尔算法

贝塞尔曲线知识就不科普了,我也不咋懂,一般也就用二阶或者三阶贝塞尔,直接上代码,也可以使用现成库

const bezier = {
  /**
   * @desc 二阶贝塞尔
   * @param {number} t 当前百分比(0~1)
   * @param {Array} p1 起点坐标
   * @param {Array} cp 控制点
   * @param {Array} p2 终点坐标
   */
  quad(t, p1, cp, p2) {
    const [x1, y1] = p1;
    const [cx, cy] = cp;
    const [x2, y2] = p2;
    const x = Math.pow(1 - t, 2) * x1 + 2 * (1 - t) * t * cx + Math.pow(t, 2) * x2;
    const y = Math.pow(1 - t, 2) * y1 + 2 * (1 - t) * t * cy + Math.pow(t, 2) * y2;
    return [x, y];
  },
  /**
   * @desc 三阶贝塞尔
   * @param {number} t 当前百分比(0~1)
   * @param {Array} p1 起点坐标
   * @param {Array} cp1 控制点1
   * @param {Array} cp2 控制点2
   * @param {Array} p2 终点坐标
   */
  cubic(t, p1, cp1, cp2, p2) {
    const [x1, y1] = p1;
    const [x2, y2] = p2;
    const [cx1, cy1] = cp1;
    const [cx2, cy2] = cp2;
    const x = Math.pow(1 - t, 3) * x1 + 3 * Math.pow(1 - t, 2) * t * cx1 + 3 * (1 - t) * Math.pow(t, 2) * cx2 + Math.pow(t, 3) * x2;
    const y = Math.pow(1 - t, 3) * y1 + 3 * Math.pow(1 - t, 2) * t * cy1 + 3 * (1 - t) * Math.pow(t, 2) * cy2 + Math.pow(t, 3) * y2;
    return [x, y];
  },
};
复制代码

先写个 demo 测试一下算法

用 canvas 测试一下上边的算法是否可用,归根揭底,上边贝塞尔函数中的参数 t 是代表了百分比或者理解为进度(0 ~ 1),所以曲线精度完全取决于每次的 t 值间隔

玩点炫的(情人节限定版)

这里为了方便我使用了 web animation api,贝塞尔曲线只是个算法,如果你愿意,你完全可以使用任意你想要的方式

猜你喜欢

转载自juejin.im/post/7110589286012944391
今日推荐