我想学前端动画-前端的贝塞尔

我想学前端动画

最近想学习前端动画,准备先从css3的动画开始。
css3的动画主要是

  • transition
  • animation

transition有animation-timing-function
animation有animation-timing-function
均内置 ease,linear,ease-in,ease-out,ease-in-out。
还可以自定义cubic-bizier(n,n,n,n), 这个嘛玩意呢,三阶贝塞尔曲线。


说道这里, 回想一下我们前端在哪些地方还会贝塞尔呢。

  • svg
  • canvas/webgl
  • css3 动画

说过了,本人想学前端动画,于是这个坎过不去。


什么是贝尔赛曲线。

贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。
再多的就自己查google, 什么google用不了? 程序员不会FQ? oh, no!

通用公式

f9dcd100baa1cd11675be878b812c8fcc2ce2dfc.jpg

线性公式

91529822720e0cf34f59dca30b46f21fbe09aa38.jpg

二次方公式

11385343fbf2b21129581916cb8065380cd78e70.jpg

三次方公式

f603918fa0ec08fad54f8dff58ee3d6d55fbda1f.jpg

再多的,额, 暂时学不动了。

一阶二阶三阶封装

接下来我们,我们如果要取点怎么办呢? 不要着急。
代码不多, 这就是基于上面公式的简单封装,
你传入需要的点数量和相应的控制点就能获得相应一组点的信息。

class Bezier {
  getPoints(count = 100, ...points) {
    const len = points.length;
    if (len < 2 || len > 4) {
      throw new Error("参数points的长度应该大于等于2小于5");
    }
    const fn =
      len === 2
        ? this.firstOrder
        : len === 3
        ? this.secondOrder
        : this.thirdOrder;
    const retPoints = [];
    for (let i = 0; i < count; i++) {
      retPoints.push(fn.call(null, i / count, ...points));
    }
    return retPoints;
  }

  firstOrder(t, p0, p1) {
    const { x: x0, y: y0 } = p0;
    const { x: x1, y: y1 } = p1;
    const x = (x1 - x0) * t;
    const y = (y1 - y0) * t;
    return { x, y };
  }

  secondOrder(t, p0, p1, p2) {
    const { x: x0, y: y0 } = p0;
    const { x: x1, y: y1 } = p1;
    const { x: x2, x: y2 } = p2;
    const x = (1 - t) * (1 - t) * x0 + 2 * t * (1 - t) * x1 + t * t * x2;
    const y = (1 - t) * (1 - t) * y0 + 2 * t * (1 - t) * y1 + t * t * y2;
    return { x, y };
  }

  thirdOrder(t, p0, p1, p2, p3) {
    const { x: x0, y: y0 } = p0;
    const { x: x1, y: y1 } = p1;
    const { x: x2, y: y2 } = p2;
    const { x: x3, y: y3 } = p3;
    let x =
      x0 * Math.pow(1 - t, 3) +
      3 * x1 * t * (1 - t) * (1 - t) +
      3 * x2 * t * t * (1 - t) +
      x3 * t * t * t;
    let y =
      y0 * (1 - t) * (1 - t) * (1 - t) +
      3 * y1 * t * (1 - t) * (1 - t) +
      3 * y2 * t * t * (1 - t) +
      y3 * t * t * t;
    return { x, y };
  }
}

export default new Bezier();

可能,你觉得太空洞,那么我们看一下demo和截图。
演示地址https://xiangwenhu.github.io/Bezier/
2.png
3.png

到此完了么? 没有!

定义三阶贝塞尔关键点

回到最开始, animation和 transition都可以自定义三阶贝塞尔函数, 而需要的就是两个控制点的信息。
在线取三阶贝塞尔关键的方案早就有了。

在线贝塞尔
在线贝塞尔2

但是不妨碍我自己去实现一个简单,方便我加强理解。
大致的实现思路

  • canvas 绘制效果
  • 两个控制点用dom元素来显示

逻辑

  • 点击时计算最近的点,同时修改最近点的坐标
  • 重绘

当然这只是一个简单的版本。

演示地址: https://xiangwenhu.github.io/Bezier/d.html
截图: p1p2.png

参考:

贝塞尔曲线扫盲
在线贝塞尔
在线贝塞尔2
可视化n次贝塞尔曲线及过程动画演示--大宝剑
贝塞尔曲线算法,js贝塞尔曲线路径点
贝塞尔曲线算法之JS获取点
https://github.com/mtsee/Bezier/blob/master/src/bezier.js
n 阶贝塞尔曲线计算公式实现
前端贝塞尔曲线效果汇总

转载于:https://www.cnblogs.com/cloud-/p/10794205.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值