🎿现代 JavaScript —— 杂项(动画)
00 分钟
2022-9-14
2022-9-15
type
status
date
slug
summary
tags
category
icon
password
Edited
Sep 15, 2022 01:17 PM
Created
Sep 13, 2022 07:44 AM

贝塞尔曲线

贝塞尔曲线用于计算机图形绘制形状,CSS 动画和许多其他地方。
它们其实非常简单,值得学习一次并且在矢量图形和高级动画的世界里非常受用。
  • 在计算机图形学,建模,矢量图形编辑器中。字体由贝塞尔曲线描述。
  • 在 Web 开发中 — 用于 Canvas 上的图形和 SVG 格式。顺便说一下,上面的“实时”示例是用 SVG 编写的。它们实际上是一个 SVG 文档,被赋予不同的控制点做参数。
贝塞尔曲线
贝塞尔曲线用于计算机图形绘制形状,CSS 动画和许多其他地方。 它们其实非常简单,值得学习一次并且在矢量图形和高级动画的世界里非常受用。 贝塞尔曲线 由控制点定义。 这些点可能有 2、3、4 或更多。 例如,两点曲线: 三点曲线: 四点曲线: 如果仔细观察这些曲线,你会立即注意到: 控制点不总是在曲线上 这是非常正常的,稍后我们将看到曲线是如何构建的。 曲线的阶次等于控制点的数量减一 。 对于两个点我们能得到一条线性曲线(直线),三个点 - 一条二阶曲线,四个点 - 一条三阶曲线。 曲线总是在控制点的凸包内部: 由于最后一个属性,在计算机图形学中,可以优化相交测试。如果凸包不相交,则曲线也不相交。因此,首先检查凸包的交叉点可以非常快地给出"无交叉"结果。检查交叉区域或凸包更容易,因为它们是矩形,三角形等(见上图),比曲线简单的多。 贝塞尔曲线绘制的主要重点 -- 通过移动曲线,曲线 以直观明显的 方式变化。 尝试在下面的示例中使用鼠标移动控制点: 可以注意到,曲线沿切线 1 → 2 和 3 → 4 延伸。 经过一些练习后,很明显我们知道怎样通过放置控制点来获得所需要的曲线。通过连接几条曲线,我们几乎可以得到任何东西。 这里有一些例子: 贝塞尔曲线可以使用数学方程式来描述。 很快我们就能看到 -- 没必要知道它。但是为了完整性 -- 请看这里。 这些是矢量方程。 我们可以逐坐标重写它们,例如 3 点曲线:
贝塞尔曲线
 

CSS 动画

过渡

CSS 提供了四个属性来描述一个过渡:
  • transition-property
  • transition-duration
  • transition-timing-function
  • transition-delay
在 transition 中以 property duration timing-function delay 的顺序一次性定义它们,并且可以同时为多个属性设置过渡动画。

transition-timing-function

时间函数描述了动画进程在时间上的分布。它是先慢后快还是先快后慢?
这个属性接受两种值:一个贝塞尔曲线(Bezier curve)或者阶跃函数(steps)。

贝塞尔曲线(Bezier curve)

CSS 中设置一贝塞尔曲线的语法为:cubic-bezier(x2, y2, x3, y3)。这里我们只需要设置第二个和第三个值,因为第一个点固定为 (0,0),第四个点固定为 (1,1)
cubic-bezier(0.0, 0.5, 0.5 ,1.0)
notion image
CSS 提供几条内建的曲线:linearease*、ease-inease-out 和 ease-in-out
linear 其实就是 cubic-bezier(0, 0, 1, 1) 的简写

贝塞尔曲线可以使动画『超出』其原本的范围。
cubic-bezier(.5, -1, .5, 2)
反向运动
notion image

阶跃函数(Steps)

时间函数 steps(number of steps[, start/end]) 允许你让动画分段进行,number of steps 表示需要拆分为多少段。
  • steps 的第一个参数表示段数。这个过渡动画将会被拆分为 9 个部分(每个占 10%)。时间间隔也会以同样的方式被拆分:9 秒会被分割为多个时长 1 秒的间隔。
  • 第二个参数可以取 start 或 end 两者其一。
    • end 表示:改变不应该在最开始的时候发生,而是发生在每一段的最后时刻。
      start 反之
steps(9, start)
把动画拆分为 9 段
简写值:
  • step-start —— 等同于 steps(1, start)。即:动画立刻开始,并且只有一段。也就是说,会立刻开始,紧接着就结束了,宛如没有动画一样。
  • step-end —— 等同于 steps(1, end)。即:在 transition-duration 结束时生成一段动画。

关键帧动画(Keyframes)

我们可以通过 CSS 提供的 @keyframes 规则整合多个简单的动画。
然后使用 animation 属性把动画绑定到相应的元素上,并为其添加额外的参数。
 

JavaScript 动画

JavaScript 动画可以处理 CSS 无法处理的事情。
例如,沿着具有与 Bezier 曲线不同的时序函数的复杂路径移动,或者实现画布上的动画。

使用 setInterval

如果我们用 setInterval 每秒做 50 次小变化,看起来会更流畅。电影也是这样的原理:每秒 24 帧或更多帧足以使其看起来流畅。

使用 requestAnimationFrame

这会让 callback 函数在浏览器每次重绘的最近时间运行。
如果我们对 callback 中的元素进行变化,这些变化将与其他 requestAnimationFrame 回调和 CSS 动画组合在一起。因此,只会有一次几何重新计算和重绘,而不是多次。
返回值 requestId 可用来取消回调:
callback 得到一个参数 —— 从页面加载开始经过的毫秒数。这个时间也可通过调用 performance.now() 得到。

结构化动画

现在我们可以在 requestAnimationFrame 基础上创建一个更通用的动画函数:
  • duration
    • 动画总时间,比如 1000
  • timing(timeFraction)
    • 时序函数,类似 CSS 属性 transition-timing-function,传入一个已过去的时间与总时间之比的小数(0 代表开始,1 代表结束),返回动画完成度(类似 Bezier 曲线中的 y)。
  • draw(progress)
    • 获取动画完成状态并绘制的函数。值 progress = 0 表示开始动画状态,progress = 1 表示结束状态。
使用:

“弹跳”文字输入

 

参考链接:
  1. 动画 (javascript.info)
 
上一篇
现代 JavaScript —— 杂项(Web Components)
下一篇
现代 JavaScript —— 杂项(在浏览器中存储数据)

评论
Loading...