反向无限淡化线

时间:2016-01-06 14:10:20

标签: css css3 css-animations

我有三个边框,底部有边框,需要淡入并从上到下淡出和反向。 如果我有2次迭代计数但无限无法正常工作,它工作正常。

.line {
  border-bottom: 0.2em solid #333;
  display: block;
  margin: 0 auto;
  margin-top: 0.3em;
  width: 1.5em;
}
.lines span[class='line']:nth-child(1) {
  animation: 1.5s ease-in-out 0.2s 2 alternate fade_line;
}
.lines span[class='line']:nth-child(2) {
  animation: 1s ease-in-out 0.7s 2 alternate fade_line;
}
.line {
  animation: 0.5s ease-in-out 1.2s 2 alternate fade_line;
}
@keyframes fade_line {
  0%, 50% {
    border-bottom: 0.2em solid #333;
  }
  50%,
  100% {
    border-bottom: 0.2em solid #ddd;
  }
}
<div class="lines">
  <span class="line"></span>
  <span class="line"></span>
  <span class="line"></span>
</div>

Fiddle Demo

2 个答案:

答案 0 :(得分:3)

动画的问题在于animation-delay实际上仅适用于动画的第一次迭代。下面解释了当只有2次迭代时它为什么起作用以及为什么它在无限次迭代时不起作用。

为什么只有2次迭代才有效?

  • 首先span0.2sanimation-delay之后)开始动画。在0.2s1.7s之间,边框颜色从#333变为#ddd0.95s50% 1.5s1.7s确切地说,在3.2s#ddd之间,它会从#333返回到2.45s(相反方向)(准确地说是span)。
  • 第二个0.7s0.7s开始动画。在1.7s#333之间,边框颜色从#ddd1.2s(精确地在1.7s)以及2.7s到{{之间1}}它从#ddd返回(反向)到#333(准确地说是2.2s)。
  • 第三个span1.2s开始动画。在1.2s1.7s之间,边框颜色从#333#ddd(精确地在1.45s)以及1.7s到{{之间1}}它从2.2s返回(反向)到#ddd(准确地说是#333)。
1.95s

正如您所看到的,只有2次迭代,它有一个很好的流程。

当迭代计数设置为无限时,为什么它不起作用?

现在让我们看看第三次和后续迭代会发生什么:

  • 首先Element | Iteration 1 | Iteration 2 --------------------------------------------------- First Span | 0.95s | 2.45s Second Span | 1.2s | 2.2s Third Span | 1.45s | 1.95s - 在span3.2s之间,边框颜色从4.7s变为#333(准确地说是#ddd)在3.95s4.7s之间,它从6.2s返回({反向} #ddd(确切地说是#333。)
  • 第二个5.45s - 在span2.7s之间,边框颜色从3.7s变为#333(精确地在#ddd)并且在3.2s3.7s之间,它从4.7s返回({反向} #ddd(确切地说是#333。)
  • 第三个4.2s - 在span2.2s之间,边框颜色从2.7s#333(准确地在#ddd处)并且在2.45s2.7s之间,它从3.2s返回({反向} #ddd(确切地说是#333。)
2.95s

正如您所看到的那样,由于动画持续时间和延迟的配置方式,动画开始重叠,因此流量完全混乱。

<强>解决方案:

通常,在无限循环动画的每次迭代之间引入延迟的方法是修改关键帧,使得它们为每次迭代添加相等的延迟。我在my answer here解释了这一点。不幸的是,由于反向动画,你的情况要复杂得多。我无法修改关键帧以符合您的期望,但我希望您能找到有助于理解问题的abov解释。

如果您乐意使用其他方法来达到相同的效果,那么您可以查看Element | Iteration 1 | Iteration 2 | Iteration 3 | Iteration 4 ------------------------------------------------------------------------------------------ First Span | 0.95s | 2.45s | 3.95s | 5.45s Second Span | 1.2s | 2.2s | 3.2s | 4.2s Third Span | 1.45s | 1.95s | 2.45s | 2.95s 背景图片来创建汉堡包效果,然后为其添加动画。

&#13;
&#13;
linear-gradient
&#13;
.lines {
  margin: 0 auto;
  height: 30px;
  width: 30px;
  background-image: linear-gradient(#333, #333), linear-gradient(#333, #333), linear-gradient(#333, #333);
  background-size: 100% 5px;
  background-position: 0px 5px, 0px 15px, 0px 25px;
  background-repeat: no-repeat;
  animation: bars 1.7s infinite alternate ease-in-out;
}
@keyframes bars {
  0% {
    background-image: linear-gradient(#333, #333), linear-gradient(#333, #333), linear-gradient(#333, #333);
  }
  33% {
    background-image: linear-gradient(#ddd, #ddd), linear-gradient(#333, #333), linear-gradient(#333, #333);
  }
  66% {
    background-image: linear-gradient(#ddd, #ddd), linear-gradient(#ddd, #ddd), linear-gradient(#333, #333);
  }
  100% {
    background-image: linear-gradient(#ddd, #ddd), linear-gradient(#ddd, #ddd), linear-gradient(#ddd, #ddd);
  }
}
&#13;
&#13;
&#13;

以下是使用您的初始方法的解决方案(由vals友情提供)。但是你无法重用关键帧!

&#13;
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="lines"></div>
&#13;
.line {
  border-bottom: 0.2em solid #333;
  display: block;
  margin: 0 auto;
  margin-top: 0.3em;
  width: 1.5em;
}
.line {
  animation: 1.7s ease-in-out infinite alternate fade_line1;
}
.line:nth-child(2) {
  animation-name: fade_line2;
}
.line:nth-child(3) {
  animation-name: fade_line3;
}
@keyframes fade_line1 { /* use 25% instead of 30% if the splits need to be equal among all 3 */
  0%, 30% {
    border-bottom-color: #333;
  }
  30%, 100% {
    border-bottom-color: #ddd;
  }
}
@keyframes fade_line2 {
  0%, 50% {
    border-bottom-color: #333;
  }
  50%, 100% {
    border-bottom-color: #ddd;
  }
}
@keyframes fade_line3 { /* use 75% instead of 70% if the splits need to be equal among all 3 */
  0%, 70% {
    border-bottom-color: #333;
  }
  70%, 100% {
    border-bottom-color: #ddd;
  }
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

使用了很长时间后,我想用svg创建一个(简单的)替代答案。

经过一个小时的javascript编码后,我将发布它到目前为止的情况。 我对代码不满意,因为它复杂并使用相当多的javascript代码来设置颜色转换的动画。

var stop = document.getElementById("stop2");

var dir = false;
var amount = 1;
var pause = false;

startanim();

function fade() {
  if (amount >= 100) {
    if (amount == 150) {
      dir = true;
    }
    amount++;
  } else if (amount <= 0) {
    if (amount == -50) {
      dir = false;
    }
    amount--;
  }
  if (dir) {
    stop.setAttribute("offset", amount + "%");
    amount--;
  } else {
    stop.setAttribute("offset", amount + "%");
    amount++;
  }
}

var interval = "id";

function startanim() {
  interval = setInterval(function() {
    fade();
  }, 10);
}
.handle {
  mask: url(#myMask);
}
<svg id="burger" viewBox="0 0 50 50" width="100" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1">
      <stop id="stop1" stop-color="black" offset="0%" />
      <stop id="stop2" stop-color="#ddd" offset="1%" />
      <stop id="stop4" stop-color="#ddd" offset="100%" />
    </linearGradient>
    <mask id="myMask" maskUnits="userSpaceOnUse" x="0" y="0" width="50" height="50">
      <rect x="0" y="0" width="50" height="50" fill="url(#Gradient1)" />
    </mask>
  </defs>
  <rect class="handle" x="20" y="12" width="30" height="5" />
  <rect class="handle" x="20" y="25" width="30" height="5" />
  <rect class="handle" x="20" y="37" width="30" height="5" />
</svg>