将CSS过渡效果设置为使用速度而不是持续时间?

21

是否可以设置 CSS 过渡效果使用速度而不是持续时间?

目前,如果我想要创建一个类来移动元素从另一个元素的左侧到右侧,则速度会有很大差异。

如果我有一个短元素,并且我想将子元素从左到右移动,持续时间设置为1秒,则移动速度非常缓慢。

另一方面,如果我有一个非常长的元素具有相同的类,则子元素以令人难以置信的速度闪过,以满足1秒的时间限制。

这真的会影响我的 CSS 模块化,所以我想知道是否有一种方法可以使这种情况下的过渡效果保持一致。


你不能设置速度。一个想到的方法是将所有移动元素设置为相同的大小,无论其内容长度如何,但这实际上取决于您现有代码的外观。 - Asons
6
基本上,“不行”。你唯一的选项是持续时间。如果你想要速度,你需要使用JavaScript进行计算。 - Paulie_D
当然,还有一件事就是你在动画中使用哪个属性。如果你能发布你的代码,那将更容易找到一种使其适用于你的方法。 - Asons
3个回答

5
不,没有transition-speed css 属性,但有一个transition-timing-function-property函数。使用该函数可以设置过渡相对于持续时间的速度,并且可以使用步骤。根据规范:

‘transition-timing-function’属性描述了在过渡期间使用的中间值将如何计算。它允许转换随着时间的推移而改变速度。这些效果通常称为缓动功能。在任一情况下,都使用提供平滑曲线的数学函数。

定时功能定义为步进函数或三次贝塞尔曲线。计时功能以其输入作为当前流逝百分比的转换持续时间并输出从其开始值到结束值的转换路径百分比方式。如何使用此输出由值类型的插值规则定义。

阶梯函数由将操作域划分为大小相等的间隔的数字定义。每个后续间隔都是接近目标状态的平均步长。该函数还指定输出百分比的更改是否发生在间隔的开头或结尾(换句话说,输入百分比上的0%是初始更改点)。

我认为此过渡时间函数属性是最接近您想要的东西,但我知道它与速度属性不同。

4
CSS没有提供这样的功能,所以你需要在JavaScript中自己计算并设置动画持续时间。
例如,考虑以下动画(持续时间固定,因此速度可变):

@keyframes slideball {
  0%   { margin-left: 0px; }
  100% { margin-left: calc(100% - 30px); }
}
.slider {
    height: 30px;
    background: blue;
    border-radius: 20px;
    margin: 10px;
    padding: 5px;
}
#slider1 {
    width: 80px;
}
#slider2 {
    width: 200px;
}
#slider3 {
    width: 500px;
}
.ball {
    height: 30px;
    width: 30px;
    border-radius: 30px;
    background: red;
    animation: slideball linear 10s forwards;
}
<div id="slider1" class="slider">
    <div class="ball"></div>
</div>
<div id="slider2" class="slider">
    <div class="ball"></div>
</div>
<div id="slider3" class="slider">
    <div class="ball"></div>
</div>

假设我们希望球体每秒前进40px,而不管包含它们的滑块有多宽。我们可以在JavaScript中计算出动画持续时间并从JavaScript设置animation样式属性:

function startAnimation(slider) {
    const ball = slider.children[0],
          speed = 40, // px per second
          distancePx = (
              slider.offsetWidth
              - parseInt(getComputedStyle(slider).paddingLeft)
              - parseInt(getComputedStyle(slider).paddingRight)
              - ball.offsetWidth
          ),
          duration = distancePx / speed;
    ball.style.animation = `slideball linear ${duration}s forwards`;
}

startAnimation(document.getElementById('slider1'));
startAnimation(document.getElementById('slider2'));
startAnimation(document.getElementById('slider3'));
@keyframes slideball {
  0%   { margin-left: 0px; }
  100% { margin-left: calc(100% - 30px); }
}
.slider {
    height: 30px;
    background: blue;
    border-radius: 20px;
    margin: 10px;
    padding: 5px;
}
#slider1 {
    width: 80px;
}
#slider2 {
    width: 200px;
}
#slider3 {
    width: 500px;
}
.ball {
    height: 30px;
    width: 30px;
    border-radius: 30px;
    background: red;
}
<div id="slider1" class="slider">
    <div class="ball"></div>
</div>
<div id="slider2" class="slider">
    <div class="ball"></div>
</div>
<div id="slider3" class="slider">
    <div class="ball"></div>
</div>

是的,这有点啰嗦和烦人,特别是当你计算包含多个边距、填充、边框等时的移动距离时,可能会变得有点复杂。但是目前CSS没有更好的工具可供使用,因此你必须采用类似这样的方法。


2
我认为这篇帖子实际上回答了楼主的问题。 - IOIIOOIO

1
作为你无法设置速度,我制作了两个示例,在示例1中,较小的框移动得稍快,当然必须如此,因为它在同一时间范围内需要行进更长的距离。在示例2中,我通过将较大的框的持续时间设置为3秒来进行了补偿,现在它们(几乎)具有相同的速度。
最好的方法可能是根据框的大小计算要行进的距离,并使用该值计算所需的持续时间,以使框,无论大小,以相同的速度行进。

.div1 div {
    width: 100px;
    height: 100px;
    background-color: red;
    position: relative;
    animation-name: example1;
    animation-duration: 4s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}
.div2 div {
    width: 200px;
    height: 200px;
    background-color: blue;
    position: relative;
    animation-name: example2;
    animation-duration: 4s;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}


@keyframes example1 {
    0%   {left:0px; top:0px;}
    100%  {left:400px; top:0px;}
}
@keyframes example2 {
    0%   {left:0px; top:0px;}
    100%  {left:300px; top:0px;}
}


.div3 div {
  width: 100px;
  height: 100px;
  background-color: red;
  position: relative;
  animation-name: example3;
  animation-duration: 4s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}
.div4 div {
  width: 200px;
  height: 200px;
  background-color: blue;
  position: relative;
  animation-name: example4;
  animation-duration: 3s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}


@keyframes example3 {
  0%   {left:0px; top:0px;}
  100%  {left:400px; top:0px;}
}
@keyframes example4 {
  0%   {left:0px; top:0px;}
  100%  {left:300px; top:0px;}
}
<br>Sample 1<br>

<div class="div1">
  <div></div>
</div>
<div class="div2">
  <div></div>
</div>

<br>Sample 2<br>

<div class="div3">
  <div></div>
</div>
<div class="div4">
  <div></div>
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接