zoukankan      html  css  js  c++  java
  • 我想学前端动画-前端的贝塞尔

    我想学前端动画

    最近想学习前端动画,准备先从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用不了? 程序员不会翻墙? oh, no!

    通用公式

    线性公式

    二次方公式

    三次方公式

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

    一阶二阶三阶封装

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

    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/

    到此完了么? 没有!

    定义三阶贝塞尔关键点

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

    在线贝塞尔
    在线贝塞尔2

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

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

    逻辑

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

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

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

    参考:

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

  • 相关阅读:
    2019.8.30 玉米田
    2019暑假集训 最短路计数
    2019暑假集训 旅行计划
    2019暑假集训 文件压缩
    0033-数字和星期转换
    0032-分数等级转换
    0031-闰年判断
    0030-购买衣服
    0029-求最小的数
    0028-判断奇偶
  • 原文地址:https://www.cnblogs.com/cloud-/p/10794205.html
Copyright © 2011-2022 走看看