将CSS转换设置为使用速度而不是持续时间



是否可以将CSS转换设置为使用速度而不是持续时间?

现在,如果我想要一个类,将另一个元素的元素从左向右移动,速度会有很大的变化。

如果我有短元素,并且我想将子元素从左向右移动,并且持续时间设置为例如1秒,那么它移动得非常慢。

另一方面,如果我有一个很长的元素和同一个类,那么子元素会以惊人的速度闪烁,以满足1秒的时间限制。

这确实损害了我的CSS模块化,所以我想知道在这种情况下是否有一种方法可以使转换保持一致。

否,没有transition-speed css属性,但有transition-timing-function-property

如果使用该函数,则可以设置相对于持续时间的过渡速度,也可以使用步长。根据规范:

"transition timing function"属性描述将计算在转换期间使用的中间值。它允许转换在其持续时间内改变速度。这些效应通常被称为缓和函数。在任何一种情况下使用提供平滑曲线的数学函数。

定时函数被定义为步进函数或三次函数Bézier曲线。定时功能将电流作为其输入转换持续时间的经过百分比,并输出从初始值到最终值。如何使用此输出由插值定义值类型的规则。

步进函数由一个数定义,该数将操作成大小相等的间隔。每个后续间隔都是离目标状态又近了一步。该函数还指定输出百分比的变化是发生在间隔(换句话说,如果输入百分比为0%初始变化点)。

我相信这个转换时间函数属性是最接近你想要的东西,但我知道它与速度属性不同。

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目前没有为您提供任何更好的工具,所以您只能使用这样的方法。

由于无法设置速度,我制作了两个样本,其中较小的盒子在样本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>

相关内容

  • 没有找到相关文章

最新更新