【问题标题】:Set CSS transition to use speed instead of duration?将 CSS 过渡设置为使用速度而不是持续时间?
【发布时间】:2016-01-10 21:55:37
【问题描述】:

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

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

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

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

这真的伤害了我的 CSS 模块化,所以我想知道在这种情况下是否有办法使过渡保持一致。

【问题讨论】:

  • 您无法设置速度。想到的一种方法是将所有移动元素设置为相同的大小,无论内容长度如何,但这实际上取决于您现有代码的外观。
  • 基本上...“不”。您唯一的选择是持续时间。如果你想要速度,你必须使用 javascript 来计算它。
  • 另外一件事当然是你在制作动画时使用的属性。最好是发布您的代码,这样可以更轻松地找到一种适合您的方法。

标签: html css css-transitions


【解决方案1】:

不,没有transition-speed css 属性,但是有一个transition-timing-function-property

如果您使用该功能,您可以设置相对于持续时间的过渡速度,也可以使用步骤。根据规范:

“transition-timing-function”属性描述了 将计算过渡期间使用的中间值。它 允许过渡在其持续时间内改变速度。这些 效果通常称为缓动函数。在任何一种情况下,一个 使用提供平滑曲线的数学函数。

时序函数定义为步进函数或三次函数 贝塞尔曲线。计时功能将电流作为其输入 过渡持续时间的经过百分比并输出 转换方式从其起始值到它的百分比 终值。如何使用此输出由插值定义 值类型的规则。

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

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

【讨论】:

    【解决方案2】:

    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>

    假设我们希望球以每秒 40 像素的速度前进,而不管包含它们的滑块有多宽。然后我们可以在 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 目前没有为您提供更好的工具来使用,所以您只能使用这样的方法。

    【讨论】:

    • 我认为这篇文章实际上回答了 OP
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2016-09-20
      • 1970-01-01
      • 2014-02-17
      • 2015-08-27
      • 2014-06-26
      • 2019-10-28
      • 2011-03-16
      • 1970-01-01
      • 2020-01-29
      相关资源
      最近更新 更多