【问题标题】:Transition right after animation动画后立即过渡
【发布时间】:2018-04-04 22:06:27
【问题描述】:

在我的元素上,只要它有一个特定的类 (wiggle),我就会运行一个 CSS 动画,并且只要它有一个不同的类 (right),就会运行一个过渡:

<div class="outer">
  <div class="inner wiggle"></div>
</div>
@keyframes wiggle {
  from {
    left: 10%;
  }
  50% {
    left: 30%;
  }
  to {
    left: 10%;
  }
}

.inner {
  left: 0;

  &.wiggle {
    animation: wiggle 2s infinite;
  }

  &.right {
    left: 90%;
    transition: left 2s;
  }
}

现在,如果删除wiggle 类并同时添加right,则过渡不会播放; left: 90% 立即适用。但是,如果删除前者和添加后者之间存在延迟,则转换将按预期进行。

Here's a JSFiddle illustrating the issue.

看起来当来自动画时,值(例如 left 在这种情况下)没有明确的值来转换,所以它们只是呈现到它们的最终状态。

这是预期的行为,即它是规范的一部分吗?或者浏览器是否免费如何处理这种情况?

我已经在最新版本的 Firefox 和 Chromium 上进行了测试。


澄清: 我主要不是在寻找变通办法,尤其是不复杂的变通办法,但更多是出于为什么浏览器的行为与它们完全相同的原因。

【问题讨论】:

  • 我认为这可能是浏览器渲染中的一个错误,但如果你想要一个解决方案,我可以给你一个 transform.!
  • @Jeremy 第一个看起来是由相同的行为引起的,但不是完全相同的问题,第二个略有不同,至少它的解决方案适用于我的情况。
  • @webBer 好吧,我也在尝试对其他属性做类似的事情,left 最容易可视化和隔离问题。例如,opacity 没有这样的解决方法。
  • @CedricReichenbach 我不是说同样的问题,抱歉。但我提到这两者都有相同的原因。因为你不能在同一个元素上拥有animation transition

标签: css css-transitions css-animations


【解决方案1】:

我认为这可能是浏览器渲染中的一个错误,但如果您需要解决方案,我可以为您提供另一种方法,transform

适合你的小提琴:

$('#toggle').click(() => {
  $('.inner').removeClass('wiggle').addClass('right');
});
@keyframes wiggle {
  from {
    left: 10%;
  }
  50% {
    left: 30%;
  }
  to {
    left: 10%;
  }
}

.outer {
  height: 5em;
  background-color: black;
  position: relative;
}

.inner {
  height: 100%;
  width: 10%;
  position: absolute;
  transform: translate(0%);
  background-color: green;
  transition: transform 2s ease-in-out;
}

.inner.wiggle {
  animation: wiggle 2s infinite;
}

.inner.right {
  transform: translate(900%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>
  Animated
</h2>
<div class="outer">
  <div class="inner wiggle"></div>
</div>
<h2>
  Not animated
</h2>
<div class="outer">
  <div class="inner"></div>
</div>
<hr>
<button id="toggle">
move right
</button>

我希望这对你有帮助。

【讨论】:

  • 正如我在其他评论中提到的,这只是使用其他 CSS 属性的一种解决方法。但是,我正在寻找适用于任何财产的通用解决方案。
  • @CedricReichenbach 知道了,兄弟。可能有人给你一个通用的解决方案,所以它也可以帮助我:)
【解决方案2】:

它看起来是预期的行为。我认为当您使用left:90% 添加right 类时,它无法选择left css 属性的起始值。作为替代方案,您可以为 .right 类创建另一个关键帧

$('#toggle').click(() => {
  $('.inner').removeClass('wiggle').addClass('right');
});
@keyframes wiggle {
  0% {
    left: 10%;
  }
  50% {
    left: 30%;
  }
  100% {
    left: 10%;
  }
}

@keyframes right {
  100% {
    left: 90%;
  }
}

.outer {
  height: 5em;
  background-color: black;
  position: relative;
}

.inner {
  height: 100%;
  width: 10%;
  position: absolute;
  left: 0;
  background-color: green;
  transition: left 2s;
}

.wiggle {
  animation: wiggle 2s infinite;
}

.right {
  animation: right 2s forwards;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>
  Animated
</h2>
<div class="outer">
  <div class="inner wiggle"></div>
</div>
<h2>
  Not animated
</h2>
<div class="outer">
  <div class="inner"></div>
</div>
<hr>
<button id="toggle">
move right
</button>

【讨论】:

    【解决方案3】:

    这个变通方法可能对你有帮助,想法是使用css variables,想法是用替代函数设置动画,所以这样我们只需要From和To...另一方面我们需要为每次迭代设置和事件,这样我们就知道迭代何时结束,

    所以当我们点击按钮时,你可以改变变量值并移除类...

    $('#toggle').click(() => {
      $('.inner').addClass('right');
    });
    let flag = false;
    $(".inner").on("animationiteration webkitAnimationIteration oAnimationIteration MSAnimationIteration", function(){ 
      flag && $(".inner").removeClass('wiggle');
      if($(".inner").hasClass('right')) flag = true;  
    });
    :root {
         --from: 10%;
         --to: 30%;
       }
       
       
    @keyframes wiggle {
      from {
        left: var(--from);
      }
    
      to {
        left: var(--to);
      }
    }
    
    .outer {
      height: 5em;
      background-color: black;
      position: relative;
    }
    
    .inner {
      height: 100%;
      width: 10%;
      position: absolute;
      transform: translate(0%);
      background-color: green;
      transition: transform 2s ease-in-out;
      left:90%;
    }
    
    .inner.wiggle {
      left:10%;
      animation: wiggle 1s infinite;
      animation-direction: alternate;
    }
    
    .inner.right {
      --to:90%;
      animation-direction: normal;
      animation-duration:2s;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <h2>
      Animated
    </h2>
    <div class="outer">
      <div class="inner wiggle"></div>
    </div>
    <hr>
    <button id="toggle">
    move right
    </button>

    考虑到当动画移回起点时这有一个错误......

    【讨论】:

    • 嗯,有趣的方法;所以不是禁用动画,我们只是改变它。但是,它仍然是一种解决方法并且非常复杂。我主要不是在寻找一个完美的解决方法,而更多是为了它的行为方式。
    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 2013-09-27
    • 2016-02-23
    • 1970-01-01
    • 2015-04-11
    • 2012-03-01
    • 2016-02-26
    • 2016-11-01
    相关资源
    最近更新 更多