简体   繁体   English

CSS关键帧动画逐渐减慢

[英]CSS Keyframe Animations progressively slowing down

I'm creating a write-on animation (much like a typewriter) over several lines. 我在几行上创建了一个写入动画(很像打字机)。 All is working relatively well, but each line of text is taking longer to resolve/animate than the previous line. 所有这些都运行得相对较好,但每行文本比前一行需要更长的时间来解析/动画。 Any help is much appreciated. 任何帮助深表感谢。

 body { background: #272822; padding-top: 10px; } li { color: white; font-family: "Courier"; font-size: 16px; margin: 10px 0 0 10px; white-space: nowrap; overflow: hidden; width: 30em; animation: type 1.5s steps(30, end); } li:nth-child(2) { animation: type2 1.5s steps(60, end); } li:nth-child(3) { animation: type2 2.5s steps(60, end); } li:nth-child(4) { animation: type2 4.25s steps(60, end); } li:nth-child(5) { animation: type2 5.5s steps(60, end); } li:nth-child(6) { animation: type2 7s steps(60, end); } .red { color: red; } .green { color: green; } .white { color: white; } .yellow { color: yellow; } @keyframes type { from { width: 0; } } @keyframes type2 { 0% { width: 0; } 50% { width: 0; } 100% { width: 100; } } 
 <div class="codeWriteOn"> <ul class="MonokaiBright"> <li> <span>&#x3c;</span><span class="red">ul</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;markup&#8221;</span><span>&#x3e;</span> </li> <li class="project1"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project1&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-1&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project2"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project2&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-2&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project3"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project3&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-3&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project4"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project4&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-4&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li> &#x3c;</span><span class="red">/ul</span><span>&#x3e;</span> </li> </ul> </div> 

The answer provided by spacegeek224 is on the right track but it is partial and that's why you still see a problem with it. spacegeek224提供的答案是在正确的轨道上,但它是部分的,这就是为什么你仍然看到它的问题。

As per your code, the initial width of the li element is 30em and in the animation's keyframes it is specified that the width should animate from 0em . 根据你的代码, li元素的初始width30em并且在动画的关键帧中指定width应该from 0em动画。 When an animation-delay is set on a element and animation-fill-mode: backwards is not specified, the element would continue to hold the state specified outside the @keyframes until the delay time is elapsed. 当在元素上设置animation-delay并且animation-fill-mode: backwards未指定animation-fill-mode: backwards ,该元素将继续保持在@keyframes之外指定的状态,直到经过延迟时间。 This is why all the li were visible to you from the start itself. 这就是为什么所有的li从一开始就可见。

If animation-fill-mode: backwards is specified, the element would continue to hold the state as at its first keyframe (which is 0% or from ) till the delay time is elapsed. 如果指定了animation-fill-mode: backwards ,则元素将继续保持其第一个关键帧( from 0% from )的状态,直到延迟时间结束。 So, the elements would take up the width: 0 during the delay period and thus become invisible until their animation starts. 因此,元素将在延迟期间占据width: 0 ,因此在动画开始之前变为不可见。

As per W3C Spec : 根据W3C规范

If the value for 'animation-fill-mode' is 'backwards', then the animation will apply the property values defined in the keyframe that will start the first iteration of the animation, during the period defined by 'animation-delay'. 如果“animation-fill-mode”的值为“向后”,则动画将应用在“动画延迟”定义的时间段内将启动动画的第一次迭代的关键帧中定义的属性值。

Another thing to note is that if you want all the elements to animate one after the other then their delays should be set in such a way that it is equal to the total amount of time required for all the prior elements to complete their animation. 另外需要注意的是,如果您希望所有元素一个接一个地进行动画处理,那么它们的延迟应该设置为等于所有先前元素完成动画所需的总时间。 So the delay on :nth-child(2) would be 3s , for :nth-child(3) should be 4.5s and so on. 所以延迟:nth-child(2)将是3s ,因为:nth-child(3)应该是4.5s ,依此类推。

Demo: 演示:

Applying both the aforementioned corrections, the below snippet would work as per your need. 同时应用上述更正,下面的代码段将根据您的需要工作。

 body { background: #272822; padding-top: 10px; } li { color: white; font-family: "Courier"; font-size: 16px; margin: 10px 0 0 10px; white-space: nowrap; overflow: hidden; width: 30em; animation: type 1.5s steps(30, end) backwards; } li:nth-child(2) { animation-delay: 1.5s; } li:nth-child(3) { animation-delay: 3s; } li:nth-child(4) { animation-delay: 4.5s; } li:nth-child(5) { animation-delay: 6s; } li:nth-child(6) { animation-delay: 7.5s; } .red { color: red; } .green { color: green; } .white { color: white; } .yellow { color: yellow; } @keyframes type { from { width: 0; } } @keyframes type2 { 0% { width: 0; } 50% { width: 0; } 100% { width: 100; } } 
 <div class="codeWriteOn"> <ul class="MonokaiBright"> <li> <span>&#x3c;</span><span class="red">ul</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;markup&#8221;</span><span>&#x3e;</span> </li> <li class="project1"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project1&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-1&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project2"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project2&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-2&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project3"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project3&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-3&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project4"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project4&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-4&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li> &#x3c;</span><span class="red">/ul</span><span>&#x3e;</span> </li> </ul> </div> 

Alternate Method: 替代方法:

Another way to get the animation working without adding animation-fill-mode: backwards would be to set the default width of the li element as 0 and then animate it to 30em instead of animating it from 0 . 另一种在不添加animation-fill-mode: backwards情况下使动画工作的方法是animation-fill-mode: backwards设置li元素的默认width0 ,然后将其设置to 30em而不是from 0设置动画。 This means that during the delay period the width would still be 0 and so the li would be invisible. 这意味着在延迟期间width仍然是0 ,因此li将是不可见的。

But, in this case animation-fill-mode: forwards should be added to make the li hold the state as at its final keyframe. 但是,在这种情况下,应该添加animation-fill-mode: forwards以使li保持其最终关键帧的状态。 Otherwise, it would go back to being invisible ( width: 0 ) after completion of the animation. 否则,它将在动画完成后返回到不可见( width: 0 )。

 body { background: #272822; padding-top: 10px; } li { color: white; font-family: "Courier"; font-size: 16px; margin: 10px 0 0 10px; white-space: nowrap; overflow: hidden; width: 0; animation: type 1.5s steps(30, end) forwards; } li:nth-child(2) { animation-delay: 1.5s; } li:nth-child(3) { animation-delay: 3s; } li:nth-child(4) { animation-delay: 4.5s; } li:nth-child(5) { animation-delay: 6s; } li:nth-child(6) { animation-delay: 7.5s; } .red { color: red; } .green { color: green; } .white { color: white; } .yellow { color: yellow; } @keyframes type { to { width: 30em; } } @keyframes type2 { 0% { width: 0; } 50% { width: 0; } 100% { width: 100; } } 
 <div class="codeWriteOn"> <ul class="MonokaiBright"> <li> <span>&#x3c;</span><span class="red">ul</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;markup&#8221;</span><span>&#x3e;</span> </li> <li class="project1"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project1&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-1&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project2"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project2&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-2&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project3"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project3&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-3&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project4"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project4&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-4&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li> &#x3c;</span><span class="red">/ul</span><span>&#x3e;</span> </li> </ul> </div> 


Note: 注意:

In the above snippet, it may look as though there is a lengthy delay/pause after the first line but that is not a problem with keyframes. 在上面的代码片段中,看起来好像在第一行之后有一个很长的延迟/暂停,但这不是关键帧的问题。 It is because the element is still animating to its full width ( 30em ) even after the entire text has become visible. 这是因为即使在整个文本变得可见之后,元素仍然以其全宽( 30em )为动画。

In the below snippet, I have added a background for each li element so that you can visually see what I mean. 在下面的代码片段中,我为每个li元素添加了一个background ,以便您可以直观地看到我的意思。

 body { background: #272822; padding-top: 10px; } li { color: white; font-family: "Courier"; font-size: 16px; margin: 10px 0 0 10px; white-space: nowrap; overflow: hidden; width: 30em; background: mediumslateblue; animation: type 1.5s steps(30, end) backwards; } li:nth-child(2) { animation-delay: 1.5s; } li:nth-child(3) { animation-delay: 3s; } li:nth-child(4) { animation-delay: 4.5s; } li:nth-child(5) { animation-delay: 6s; } li:nth-child(6) { animation-delay: 7.5s; } .red { color: red; } .green { color: green; } .white { color: white; } .yellow { color: yellow; } @keyframes type { from { width: 0; } } @keyframes type2 { 0% { width: 0; } 50% { width: 0; } 100% { width: 100; } } 
 <div class="codeWriteOn"> <ul class="MonokaiBright"> <li> <span>&#x3c;</span><span class="red">ul</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;markup&#8221;</span><span>&#x3e;</span> </li> <li class="project1"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project1&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-1&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project2"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project2&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-2&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project3"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project3&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-3&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li class="project4"> &nbsp;&nbsp;<span>&#x3c;</span><span class="red">li</span> <span class="green">class</span>&#61;<span class="yellow">&#8220;project4&#8221;</span><span>&#x3e;</span> <!-- ">" --><span>Project-4&#x3c;</span><span class="red">/li</span><span>&#x3e;</span> </li> <li> &#x3c;</span><span class="red">/ul</span><span>&#x3e;</span> </li> </ul> </div> 

Instead of increasing the animation time for each one, use animation-delay: 1s (replace 1s with your delay), and change the animation time for each li to the same number. 不要增加每个动画的动画时间,而是使用animation-delay: 1s (用延迟替换1s ),并将每个li的动画时间更改为相同的数字。

Example: 例:

li {
  color: white;
  font-family: "Courier";
  font-size: 16px;
  margin: 10px 0 0 10px;
  white-space: nowrap;
  overflow: hidden;
  width: 30em;
  animation: type 1.5s steps(30, end);
}
li:nth-child(2) {
  animation: type2 1.5s steps(60, end);
}
li:nth-child(3) {
  animation: type2 1.5s steps(60, end);
animation-delay: 1s;
}
li:nth-child(4) {
  animation: type2 1.5s steps(60, end);
animation-delay: 2.75s;
}
li:nth-child(5) {
  animation: type2 1.5s steps(60, end);
animation-delay: 4s;
}
li:nth-child(6) {
  animation: type2 1.5s steps(60, end);
animation-delay: 6.5s;
}

I'm not really sure what your question is, but maybe I'm going to assume that you don't want it to go slower and slower. 我不确定你的问题是什么,但也许我会假设你不希望它变得越来越慢。 If that's the case you need to delete these lines 如果是这种情况,您需要删除这些行

    li:nth-child(2) {
      animation: type2 1.5s steps(60, end);
    }
    li:nth-child(3) {
      animation: type2 2.5s steps(60, end);
    }
    li:nth-child(4) {
      animation: type2 4.25s steps(60, end);
    }
    li:nth-child(5) {
      animation: type2 5.5s steps(60, end);
    }
    li:nth-child(6) {
      animation: type2 7s steps(60, end);
    }

Those 1.5s , 2.5s , etc values are slowing it down. 那些1.5s2.5s等值正在减慢它的速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM