基于时间的 CSS 动画

在我之前的文章《CSS 动画的时间统一》中,我记录了一种使用 CSS 动画进行制作的方法 时间滴答声 代替 关键帧。 由于 CSS 缺乏进行复杂数学计算的能力,它的适用范围有限。

经过多年的等待,CSS 现在已经支持了足够多的数学函数,特别是 模(), 圆形的(), 和 三角函数。 是时候重新审视基于时间的动画方式了,希望这次会更有用。

您可能需要启用 实验性功能标志 在此页面中查看演示。

基本思想

使用 时间 动画在着色器程序和其他各种地方非常常见。 CSS 无法像 JavaScript 那样启动计时器,但现在可以使用以下命令定义自定义变量: CSS 胡迪尼 API 追踪 时间 以毫秒为单位。

@property –t { 语法:”“; 初始值:0;继承:true } @keyframes tick { 从 { –t: 0 } 到 { –t: 86400000 } } :root { 动画:tick 86400000ms 线性无限 }

对于每毫秒,变量 –t 增加 1,即一秒 1000。 有一个技巧可以显示变量 柜台() 功能。

::after { 计数器重置:t var(–t); 内容:计数器

其他基于 –t 的值也会随之改变。 这就是我们得到的 动画片 影响。

div { /* 每秒 1 圈 */rotate: calc(var(–t) * .001turn); }

控制帧速率

将更新频率保持在 60 帧每秒 (FPS) 足以实现流畅的动画。 浏览器通常会对渲染进行优化,因此如果频率高于 60 FPS,就不会有任何问题。 但可以使用手动控制帧速率 步()
如果需要的话可以使用。

/* … */ :root { 动画: 勾选; 动画持续时间:86400000ms; 动画迭代次数:无限; /* 8 fps */ 动画计时函数:step(calc(86400000/(1000/8))); /* 24 fps */ 动画计时函数:step(calc(86400000/(1000/24))); /* 60 fps */ 动画计时函数:step(calc(86400000/(1000/60))); }

变换时间

–t 的值朝一个方向不断增长。 大于 360 度的角度值是可以的,但是,并非所有 CSS 属性都将其值视为循环。

假设我想从左到右对一个框进行动画处理,如果平移偏移量与 –t 相关联,它将不断增加而不会停止。

翻译: calc(var(–t) * .001px);

分钟()

一个预期的结果是,当偏移达到特定值时,它会立即停止。 就是这样 分钟() 功能可能会有用。

翻译:min(270px, calc(var(–t) * .5px));

为了精确控制动画持续时间,我们可以限制 –t 的值。

/* 3 秒内 270px */ 翻译: calc(min(3000, var(–t)) * (270px / 3000));

模()

框向右移动后,另一个选择是从头开始重新开始偏移。 现在我们有 模() 函数来实现这一点。

翻译: calc(mod(var(–t)/4, 270) * 1px);

罪()

或者来回移动。

翻译: calc(sin(mod(var(–t)/135, 270)) * 135px);

自定义缓动功能

我们可以使用数学函数和 –t 变量创建自定义缓动函数,这可能无法通过 三次贝塞尔曲线()

三次缓出

第一步是将 –t 值限制在 01

/* 1秒内从0到1 */ –t01: calc(min(1000, var(–t)) / 1000); /* 1 – pow(1 – t, 3) */ –ease-out-cubic: calc( 1 – pow(1 – var(–t01), 3) ); 翻译: calc(var(–ease-out-cubic) * 270px);

缓出弹性

/* 1秒内从0到1 */ –t01: calc(min(1000, var(–t)) / 1000); /* pow(2, -10t) * sin((10t – .75) * 2/3 * PI) + 1 */ –ease-out-elastic: calc( pow(2, -10 * var(– t01)) * sin((var(–t01) * 10 – .75) * 2/3 * PI) + 1 ); 翻译: calc(var(–ease-out-elastic) * 270px);

尝试 CSS 涂鸦

随着表达式变得复杂,var() 和 calc() 往往会降低代码的可读性。 所以我添加了 @t 函数来表示变量 –t。 最新版本 CSS 涂鸦 还直接在参数内接受简单的数学表达式。

/* 旋转: calc(mod(var(–t) / 1000, 10) * 5deg); */ 旋转:@t(/1000, %10, *5deg);

代码很短,不用写 关键帧

@网格:20×1 / 280x 60px; @间隙:1px; @尺寸:100% 20%; 背景:#000; 保证金:自动; 翻译:0 calc(20px * sin(4*@t(/20, +@i(*6), %360deg)));

@网格:20×1 / 280px 60px; @间隙:1px; @尺寸:100% 20%; 背景:#000; 保证金:自动; 翻译:0 calc(20px * sin(4*@t(/20, +@i(*6), %360deg))); 开始/停止

并且也可以快速尝试新参数。

翻译:0 calc(20px * sin(3*@t(/50, *@i(*2), %360deg)));

@网格:20×1 / 280px 60px; @间隙:1px; @尺寸:100% 20%; 背景:#000; 保证金:自动; 翻译:0 calc(20px * sin(3*@t(/50, *@i(*2), %360deg))); 开始/停止

函数@T和@TS

除了@t函数之外,大写的@T函数代表另一个函数 时间滴答声 从今天开始。 函数@TS 是@t(/1000) 的简写,它跟踪以秒为单位的时间。

这是一个用 css-doodle 实现的时钟。 (代码笔链接

/* … */ /* 第二个 */ 旋转: @TS(*6, %360deg); /* 分钟 */ 旋转: @TS(/60, *6, %360deg); /* 小时 */ 旋转: @TS(/60, /12, *6, %360deg);

@网格:4×1 / 240px +.9; :container { 边界半径: 50%; 边框:4px实心#000; 轮廓:10px实线; 轮廓偏移:2px; 背景: @doodle( @grid: 12×1; @content: @I(- @i(-1)); @place: @plot(r: .8; dir: -90; 旋转: -90;); 字体-大小:30px;字体系列:无衬线;粗体;@doodle(@grid:60×1;背景:#000;@size:@pn(16px,@m4(8px))@pn( 2px, @m4(1px)); @place: @plot(r: 1;); @place:中心; 剪辑路径:多边形(50%-50%, 100% 65%, 0 65%); 背景:#000; @nth(3) { @size: 4px 90%; 背景:红色; 旋转:@TS(*6, %360deg); } @nth(2) { @size: 6px 70%; 旋转:@TS(/60, *6, %360deg); } @nth(1) { @size: 10px 45%; 旋转:@TS(/60, /12, *6, %360deg); } @nth(4) { @size: 12px; 边界半径:50%; 剪辑路径:无; 背景:红色; }

圆形的()

如何让秒针做出跳跃动作? 当然,最直接的方法就是使用 圆形的() 函数,其中第三个参数指定舍入间隔。 在时钟的背景下,每一步等于 360 / 60 = 6deg。

旋转:圆形(向下,@TS(* 6,%360deg),6deg);

@网格:4×1 / 240px +.9; :container { 边界半径: 50%; 边框:4px实心#000; 轮廓:10px实线; 轮廓偏移:2px; 背景: @doodle( @grid: 12×1; @content: @I(- @i(-1)); @place: @plot(r: .8; dir: -90; 旋转: -90;); 字体-大小:30px;字体系列:无衬线;粗体;@doodle(@grid:60×1;背景:#000;@size:@pn(16px,@m4(8px))@pn( 2px, @m4(1px)); @place: @plot(r: 1;); @place:中心; 剪辑路径:多边形(50%-50%, 100% 65%, 0 65%); 背景:#000; @nth(3) { @size: 4px 90%; 背景:红色; 旋转:圆形(向下,@TS(* 6,%360deg),6deg); } @nth(2) { @size: 6px 70%; 旋转:@TS(/60, *6, %360deg); } @nth(1) { @size: 10px 45%; 旋转:@TS(/60, /12, *6, %360deg); } @nth(4) { @size: 12px; 边界半径:50%; 剪辑路径:无; 背景:红色; }

再举一个例子

将颜色和位置一起制作动画。 (代码笔链接)。

@grid: 100×1 / 100% 自动 (4/3) / #10153e; @大小:@rn(1vmin,5vmin,10); 保证金:自动; 边界半径:50%; 背景: @p( hsl(@t(/10, +@i(*2), %360), 90%, 80%) ); 框阴影: @m5( @r(±23vmin) @r(±23vmin) @r(2vmin) @r(-40px) @p ); 翻译: @M2( calc(100px * tan(6*cos(@t(/10, +@i(*10), /6, %360deg)))) );

@grid: 100×1 / 100% 自动 (4/3) / #10153e; @大小:@rn(1vmin,5vmin,10); 背景:@p(hsl(@t(/10, +@i(*2), %360), 90%, 80%)); 框阴影:@m5(@r(±23vmin) @r(±23vmin) @r(2vmin) @r(-40px) @p); 翻译: @M2( calc(100px * tan(6*cos(@t(/10, +@i(*10), /6, %360deg)))) ); 保证金:自动; 边界半径:50%;

结论

我对这种方法感到很兴奋。 虽然使用 关键帧 看起来很简单,对于充满数学计算和输入变量的演示场景,使用 时间 作为一个变量更有可能得到不同的结果。

1714894960
#基于时间的 #CSS #动画
2024-05-05 04:26:10

Leave a Reply

Your email address will not be published. Required fields are marked *

近期新闻​

编辑精选​