贝塞尔曲线在前端,走近她,然后爱上她

简介: 今天我们聊聊我们经常用的CSS3动画里面的贝尔赛曲线,希望能做到,她认识你,你也熟悉她! 本文源码: Bezier看完你就懂了一半,动手你就成功了另外一半!

1.JPG


前言



今天我们聊聊我们经常用的CSS3动画里面的贝尔赛曲线,希望能做到,她认识你,你也熟悉她! 本文源码: Bezier


看完你就懂了一半,动手你就成功了另外一半!


贝塞尔曲线在前端



css3的动画主要是


  • transition
  • animation


transition有transition-timing-function

animation有animation-timing-function

transition-timing-function为例


2.JPG


其内置 ease,linear,ease-in,ease-out,ease-in-out就是贝塞尔曲线函数, 作用是控制属性变化的速度。


也可以自定义cubic-bizier(x1,y1,x2,y2), 这个嘛玩意呢,三阶贝塞尔曲线, x1,y1x2,y2是两个控制点。


如图: x1, y1对应 P1点, x2,y2 对应P2点。


要点:

  1. 曲线越陡峭,速度越快,反之,速度越慢!
  2. 控制点的位置会影响曲线形状


3.JPG


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


  • svg
  • canvas/webgl
  • css3 动画
  • animation Web API


千万别以为JS就不能操作CSS3动画了


这样说可能有些空洞,我们一起来看看曲线和实际的动画效果:


红色ease和ease-out曲线前期比较陡峭,加速度明显比较快


4.JPG

贝塞尔曲线运动-演示地址5.JPG


什么是贝赛尔曲线



贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。


公式怎么理解呢?这里你可以假定


  • P0的坐标(0,0), 最终的点的坐标为(1,1)


t从0不断的增长到1

t的值和控制点的x坐标套入公式,得到一个新的x坐标值

t的值和控制点的y坐标套入公式,得到一个新的y坐标值


(新的x坐标值 , 新的y坐标值)坐标就是t时刻曲线的点的坐标。


通用公式


6.JPG

线性公式


无控制点,直线


7.JPG


二次方公式


一个控制点


8.JPG


三次方公式


两个控制点


9.JPG


这是我们的重点,因为css动画都是三次方程式


P0作为起点,P3作为终点, 控制点是P1与P2, 因为我们一般会假定 P0 为 (0,0), 而 P3为(1,1)。


控制点的变化,会影响整个曲线,我们一起来简单封装一下并进行实例操作。


一阶二阶三阶封装



我们基于上面公式的进行简单的封装,

你传入需要的点数量和相应的控制点就能获得相应一组点的信息。


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和截图。


演示地址: xiangwenhu.github.io/juejinBlogs…


一阶贝塞尔是一条直线:


10.JPG


二阶贝塞尔一个控制点:


11.JPG


三阶贝塞尔两个控制点:


12.JPG


贝塞尔曲线控制点




回到最开始, animation和 transition都可以自定义三阶贝塞尔函数, 而需要的就是两个控制点的信息怎么通过测试曲线获得控制点呢?


在线取三阶贝塞尔关键的方案早就有了。


在线贝塞尔

在线贝塞尔2


但是不妨碍我自己去实现一个简单,加强理解。


大致的实现思路


  • canvas 绘制效果
    canvas有bezierCurveTo方法,直接可以绘制贝塞尔曲线
  • 两个控制点用dom元素来显示


逻辑


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


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

演示地址: xiangwenhu.github.io/juejinBlogs…


截图: 13.JPG


有了这个,你就可以通过曲线获得控制点了, 之前提到过,曲线的陡峭决定了速度的快慢,是不是很有用呢?


当然,你可以自己加个贝塞尔的直线运动,查看实际的运动效果,其实都不难,难的是你不肯动手!!!



相关文章
|
设计模式 Java 程序员
日志框架Slf4j作用及其实现原理
日志框架Slf4j作用及其实现原理
264 0
|
存储 SQL 分布式计算
【存储】2022 年的 4 个开源对象存储平台
【存储】2022 年的 4 个开源对象存储平台
|
移动开发 缓存 前端开发
推荐一大波让你直呼哇塞的Canvas库【值得收藏】
推荐一大波让你直呼哇塞的Canvas库【值得收藏】
5919 0
推荐一大波让你直呼哇塞的Canvas库【值得收藏】
|
Shell 虚拟化 iOS开发
Mac下iTerm2+oh my zsh+powerlevel10k 配置与美化过程记录
Mac下iTerm2+oh my zsh+powerlevel10k 配置与美化过程记录
4080 0
Mac下iTerm2+oh my zsh+powerlevel10k 配置与美化过程记录
|
JavaScript 前端开发 算法
【vue系列-01】vue初级入门以及demo实现详解
【vue系列-01】vue初级入门以及demo实现详解
344 0
|
11月前
|
Dart 开发者 Windows
flutter:dart的学习
本文介绍了Dart语言的下载方法及基本使用,包括在Windows系统上和VSCode中的安装步骤,并展示了如何运行Dart代码。此外,还详细说明了Dart的基础语法、构造函数、泛型以及库的使用方法。文中通过示例代码解释了闭包、运算符等概念,并介绍了Dart的新特性如非空断言操作符和延迟初始化变量。最后,提供了添加第三方库依赖的方法。
136 12
|
敏捷开发 安全 测试技术
区块链开发团队DappNetWork
区块链开发团队由跨学科专家组成,包括区块链专家、智能合约开发者、系统架构师和测试工程师。团队负责战略规划、技术开发、系统测试和运维优化,需要深入理解区块链技术、安全性和敏捷开发。通过敏捷管理和自动化工具,团队实现高效协作,为金融、供应链等领域提供安全可靠的区块链应用解决方案。如需开发加V:DappNetWork
|
IDE PHP 开发工具
「Python入门」python环境搭建及VScode使用python运行方式
**Python 概述与环境搭建摘要** Python是一种解释型、面向对象、交互式的脚本语言,以其简单易学和丰富库著称。安装Python时,推荐在Windows上选择.exe安装程序,记得勾选“Add Python to PATH”。安装完成后,通过环境变量配置确保Python可被系统识别。验证安装成功,可在CMD中输入`python --version`。Visual Studio Code (VScode)是流行的Python IDE,安装Python插件并选择解释器后,可直接在VScode内编写和运行Python代码。
513 0
「Python入门」python环境搭建及VScode使用python运行方式
|
测试技术 Go 开发工具
【Go语言专栏】Go语言中的代码审查与最佳实践
【4月更文挑战第30天】Go语言因其简洁、高性能及并发能力,在云计算等领域广泛应用。代码审查对提升Go代码质量、遵循规范及团队协作至关重要。审查流程包括提交、审查、反馈、修改和合并代码。工具如GoLand、Git、ReviewBoard和GitHub提供支持。最佳实践包括遵循命名规范、添加注释、保持代码结构清晰、复用代码和确保测试覆盖。积极参与代码审查是提高质量的关键。
253 0
|
机器学习/深度学习 人工智能 算法
AI - 决策树模型
决策树算法起源于古希腊的逻辑推理,20世纪在军事策略研究中首次提出。它通过构建树形模型模拟决策过程,每个节点代表一个属性判断,分支代表可能结果。ID3算法基于信息增益,C4.5则引入信息增益率,解决了ID3偏好多值属性的问题,还能处理缺失值。CART决策树适用于分类和回归任务,使用基尼系数或信息增益来选择特征。在Python的`sklearn`库中,`DecisionTreeClassifier`实现决策树分类,通过参数如`criterion`、`max_depth`等控制模型。