纸上得来终觉浅,绝知此事要躬行
前言🎀
贝塞尔曲线是一种数学曲线,它拥有 灵活、平滑、可编辑 的特点,十分适合描述曲面形状、处理图形变形、模拟运动轨迹等场景。
使用贝塞尔曲线,我们可以绘制各种各样的图形,它对计算机的图形图像技术具有深远的影响。
我们熟知的 CSS 动画、 Canvas 以及 Photoshop 等也都可以看到贝塞尔曲线的身影。
本文我们一起学习贝塞尔曲线在前端中的基础应用,了解其实现原理~
简介
贝塞尔曲线由 控制点 组成,调整控制点曲线形状会发生变化。
贝塞尔曲线根据 控制点(P) 的数量分为:
- 一阶贝塞尔曲线(2 个控制点)
- 二阶贝塞尔曲线(3 个控制点)
. . .
- n阶贝塞尔曲线(n + 1个控制点)
应用
在前端开发中,我们使用贝塞尔曲线不限于以下几种方案:
-
CSS提供了相关的属性
animation-time-function,使用贝塞尔曲线的轨迹描述动画运行进度,让动画表现的更加平滑、自然 -
Canvas提供了API
quadraticCurveTo和bezierCurveTo,分别绘制二次贝塞尔曲线和三次贝塞尔曲线 -
直接绘制由贝塞尔曲线组成的图形,例如svg
CSS animation-time-function
CSS中animation-time-function 是 animation 属性的子属性,它代表了动画速度的曲线,CSS提供了内置的几个值让我们可以快速、便捷的使用贝塞尔曲线:
animation-time-function: ease | ease-in | ease-out | ease-in-out | linear
我们也可以通过自定义函数生成贝塞尔曲线:
animation-time-function: cubic-bezier(x1, y1, x2, y2)
例如实现一个回弹效果:
分析
在CSS动画中,使用三次贝塞尔曲线控制动画,曲线的横坐标代表时间比率,纵坐标代表动画进度。
曲线的斜率代表了动画的运动速度,曲线越陡峭,速度越快;曲线越平缓,速度则越慢。
而 ease、ease-in ... 等属性值等同于自定义cubic-bezier函数生成的曲线,具体值可以去 MDN 了解# animation-timing-function-MDN。
推荐一个可在线编辑贝塞尔曲线的网站 cubic-bezier.com/
Canvas API
Canvas提供了API:quadraticCurveTo、bezierCurveTo,用于绘制2阶、3阶贝塞尔曲线
Q: 对于更高阶的贝塞尔曲线该怎么办?
A: 平常尽量使用2-3阶贝塞尔曲线,更高阶的曲线尽量降阶为2-3阶贝塞尔曲线
下方案例演示了相关API的用法,支持拖拽控制点,并兼容了n阶曲线,你可以通过在controlPoints中添加控制点进行测试:
绘制图形
通过 CSS clip-path 从一个div中剪去两块贝塞尔的曲线覆盖的内容(本质是绘制svg),实现粘性下拉,软件与用户交互时更加顺滑
原理
贝塞尔曲线本质上是一系列点的集合,需要大量的计算。
以三次贝塞尔曲线举例:
- 贝塞尔曲线由 控制点(P) 组成,控制点之间会连接成线段
- 线段上会形成新的控制点(P')
- 新控制点之间又会连接成线段,线段又会形成控制点 (类似递归) . . .
- 直至形成的唯一控制点(图中是P''')
我们把线段上的所有控制点的进度用一个参数t = [0, 1] 表示,例:(P0 * P'0) / (P0 * P1)
参数t从0到1 所有控制点从头移动到尾,期间唯一控制点的运动轨迹便是贝塞尔曲线。
最后通过一张图片回顾贝塞尔曲线的生成过程:
通过计算公式我们可以获取曲线当前的点坐标:
-
一阶:
-
二阶:
-
三阶:
...
- N阶:
总结
最后我们总结一下本文:
- 贝塞尔曲线,一种数学曲线,特点是灵活、平滑、可编辑,适用于设计、动画、图形
- 贝塞尔曲线由控制点组成,根据 控制点数(n) 被定义为 (n - 1) 阶贝塞尔曲线
- CSS中通过
animation-time-function属性使用贝塞尔曲线的轨迹描述动画进度 - Canvas中通过
quadraticCurveTo、bezierCurveTo绘制2、3阶贝塞尔曲线,更高阶的曲线通过降阶处理 - 贝塞尔曲线形成的原理:
- 给定控制点连接成线段,线段创建新的控制点,控制点再连接成线段 . . .
- 最后形成的唯一控制点根据 进度t 生成的运动轨迹,便是贝塞尔曲线
- 贝塞尔曲线本质上是一系列点的集合,需要大量的计算
- 贝塞尔曲线的通用计算公式
结语🎉
本文比较简单,后续会更新 Canvas结合贝塞尔曲线 实现带笔锋的画板/签名版,感兴趣点关注 不迷路~
不要光看不实践哦,后续会持续更新前端相关的知识 😉
脚踏实地不水文,真的不关注一下吗~
写作不易,如果觉得有收获还望大家点赞、收藏 🌹
才疏学浅,如有问题或建议欢迎大家指教。