94

我最近发现了如何“正确”使用 CSS 动画(之前我认为它们无法像 JavaScript 那样制作复杂的序列)。所以现在我正在了解它们。

对于这种效果,我试图让渐变“耀斑”扫过类似进度条的元素。类似于原生 Windows Vista/7 进度条的效果。

@keyframes barshine {
  from {background-image:linear-gradient(120deg,rgba(255,255,255,0) -10%,rgba(255,255,255,0.25) -5%,rgba(255,255,255,0) 0%);}
  to {background-image:linear-gradient(120deg,rgba(255,255,255,0) 100%,rgba(255,255,255,0.25) 105%,rgba(255,255,255,0) 110%);}
}
.progbar {
  animation: barshine 1s 4s linear infinite;
}

正如你所看到的,我试图延迟 4 秒,然后在 1 秒内扫过光芒,重复。

然而,似乎animation-delay只适用于第一次迭代,之后闪耀只是不断地反复扫过。

我“解决”了这个问题如下:

@keyframes expbarshine {
  from {background-image:linear-gradient(120deg,rgba(255,255,255,0) -10%,rgba(255,255,255,0.25) -5%,rgba(255,255,255,0) 0%);}
  80% {background-image:linear-gradient(120deg,rgba(255,255,255,0) -10%,rgba(255,255,255,0.25) -5%,rgba(255,255,255,0) 0%);}
  to {background-image:linear-gradient(120deg,rgba(255,255,255,0) 100%,rgba(255,255,255,0.25) 105%,rgba(255,255,255,0) 110%);}
}
.progbar {
  animation: barshine 5s linear infinite;
}

from并且80%完全相同,导致动画长度的80%的“延迟”。

这可行,但是对于我的下一个动画,我需要延迟是可变的(对于特定元素是恒定的,但在使用动画的元素之间是可变的),而动画本身保持完全相同的长度。

使用上面的“解决方案”,当我想要的只是更长的延迟时,我最终会得到一个更慢的动画。

是否有可能animation-delay适用于所有迭代,而不仅仅是第一次?

4

11 回答 11

64

我有类似的问题并使用

@-webkit-keyframes pan {
   0%, 10%       { -webkit-transform: translate3d( 0%, 0px, 0px); }
   90%, 100%     { -webkit-transform: translate3d(-50%, 0px, 0px); }
}

有点恼火的是,你必须伪造你的持续时间来解释两端的“延迟”。

于 2013-07-03T11:54:00.943 回答
20

minitech 是正确的,它animation-delay指定了动画开始之前的延迟,而不是迭代之间的延迟。 规范的编辑草稿很好地描述了它,并且讨论了您在此处描述的此功能,这暗示了此迭代延迟功能。

虽然 JS 中可能有一种解决方法,但您可以仅使用 CSS 来伪造进度条耀斑的迭代延迟。

通过声明flare divposition:absolute和父 div overflow: hidden,将100% 关键帧状态设置为大于进度条的宽度,并使用cubic-bezier 计时函数和左偏移值,您可以模拟ease-in-outlinear计时延迟”。

编写一个less/scss mixin 来精确计算左偏移和计时函数来得到这个精确值会很有趣,但我现在没有时间摆弄它。不过很想看到这样的东西!

这是我拼凑的一个演示,以展示这一点。(我试图模拟 Windows 7 进度条并有点短,但它说明了我在说什么)

演示: http ://codepen.io/timothyasp/full/HlzGu

<!-- HTML -->
<div class="bar">
   <div class="progress">
      <div class="flare"></div>
   </div>
</div>


/* CSS */

@keyframes progress {
  from {
    width: 0px;
  }
  to {
    width: 600px;
  }
}

@keyframes barshine {
  0% {
    left: -100px;
  }

  100% {
    left: 1000px;
  }
}
.flare {
  animation-name: barshine;
  animation-duration: 3s;
  animation-direction: normal;
  animation-fill-mode: forwards;
  animation-timing-function: cubic-bezier(.14, .75, .2, 1.01);
  animation-iteration-count: infinite;
  left: 0;
  top: 0;
  height: 40px;
  width: 100px;
  position: absolute;
  background: -moz-radial-gradient(center, ellipse cover,  rgba(255,255,255,0.69) 0%, rgba(255,255,255,0) 87%); /* FF3.6+ */
  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(255,255,255,0.69)), color-stop(87%,rgba(255,255,255,0))); /* Chrome,Safari4+ */
  background: -webkit-radial-gradient(center, ellipse cover,  rgba(255,255,255,0.69) 0%,rgba(255,255,255,0) 87%); /* Chrome10+,Safari5.1+ */
  background: -o-radial-gradient(center, ellipse cover,  rgba(255,255,255,0.69) 0%,rgba(255,255,255,0) 87%); /* Opera 12+ */
  background: -ms-radial-gradient(center, ellipse cover,  rgba(255,255,255,0.69) 0%,rgba(255,255,255,0) 87%); /* IE10+ */
  background: radial-gradient(ellipse at center,  rgba(255,255,255,0.69) 0%,rgba(255,255,255,0) 87%); /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b0ffffff', endColorstr='#00ffffff',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
  z-index: 10;
}
.progress {
  animation-name: progress;
  animation-duration: 10s;
  animation-delay: 1s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  overflow: hidden;
  position:relative;
  z-index: 1;
  height: 100%;
  width: 100%;
  border-right: 1px solid #0f9116;
  background: #caf7ce; /* Old browsers */
  background: -moz-linear-gradient(top, #caf7ce 0%, #caf7ce 18%, #3fe81e 45%, #2ab22a 96%); /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#caf7ce), color-stop(18%,#caf7ce), color-stop(45%,#3fe81e), color-stop(96%,#2ab22a)); /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #caf7ce 0%,#caf7ce 18%,#3fe81e 45%,#2ab22a 96%); /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #caf7ce 0%,#caf7ce 18%,#3fe81e 45%,#2ab22a 96%); /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #caf7ce 0%,#caf7ce 18%,#3fe81e 45%,#2ab22a 96%); /* IE10+ */
  background: linear-gradient(to bottom, #caf7ce 0%,#caf7ce 18%,#3fe81e 45%,#2ab22a 96%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#caf7ce', endColorstr='#2ab22a',GradientType=0 ); /* IE6-9 */
}

.progress:after {
  content: "";
  width: 100%;
  height: 29px;
  right: 0;
  bottom: 0;
  position: absolute;
  z-index: 3;
  background: -moz-linear-gradient(left, rgba(202,247,206,0) 0%, rgba(42,178,42,1) 100%); /* FF3.6+ */
  background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(202,247,206,0)), color-stop(100%,rgba(42,178,42,1))); /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(left, rgba(202,247,206,0) 0%,rgba(42,178,42,1) 100%); /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(left, rgba(202,247,206,0) 0%,rgba(42,178,42,1) 100%); /* Opera 11.10+ */
  background: -ms-linear-gradient(left, rgba(202,247,206,0) 0%,rgba(42,178,42,1) 100%); /* IE10+ */
  background: linear-gradient(to right, rgba(202,247,206,0) 0%,rgba(42,178,42,1) 100%); /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00caf7ce', endColorstr='#2ab22a',GradientType=1 ); /* IE6-9 */
}

.bar {
  margin-top: 30px;
  height: 40px;
  width: 600px;
  position: relative;
  border: 1px solid #777;
  border-radius: 3px;
}
于 2012-12-18T06:18:20.597 回答
11

这是你应该做的。它应该起作用,因为您有 1 秒的动画,然后在迭代之间有 4 秒的延迟:

@keyframes barshine {
  0% {
  background-image:linear-gradient(120deg,rgba(255,255,255,0) 0%,rgba(255,255,255,0.25) -5%,rgba(255,255,255,0) 0%);
  }
  20% {
    background-image:linear-gradient(120deg,rgba(255,255,255,0) 10%,rgba(255,255,255,0.25) 105%,rgba(255,255,255,0) 110%);
  }
}
.progbar {
  animation: barshine 5s 0s linear infinite;
}

所以我一直在搞砸这件事,你可以做到这一点而不会很笨拙。这是在动画迭代之间设置延迟的最简单方法,即 1. SUPER EASY 和 2. 只需要一点逻辑。看看我制作的这个舞蹈动画:

.dance{
  animation-name: dance;
  -webkit-animation-name: dance;

  animation-iteration-count: infinite;
  -webkit-animation-iteration-count: infinite;
  animation-duration: 2.5s;
  -webkit-animation-duration: 2.5s;

  -webkit-animation-delay: 2.5s;
  animation-delay: 2.5s;
  animation-timing-function: ease-in;
  -webkit-animation-timing-function: ease-in;

}
@keyframes dance {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  25% {
    -webkit-transform: rotate(-120deg);
    -moz-transform: rotate(-120deg);
    -o-transform: rotate(-120deg);
    -ms-transform: rotate(-120deg);
    transform: rotate(-120deg);
  }
  50% {
    -webkit-transform: rotate(20deg);
    -moz-transform: rotate(20deg);
    -o-transform: rotate(20deg);
    -ms-transform: rotate(20deg);
    transform: rotate(20deg);
  }
  100% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
  }
}

@-webkit-keyframes dance {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  20% {
    -webkit-transform: rotate(20deg);
    -moz-transform: rotate(20deg);
    -o-transform: rotate(20deg);
    -ms-transform: rotate(20deg);
    transform: rotate(20deg);
  }
  40% {
    -webkit-transform: rotate(-120deg);
    -moz-transform: rotate(-120deg);
    -o-transform: rotate(-120deg);
    -ms-transform: rotate(-120deg);
    transform: rotate(-120deg);
  }
  60% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  80% {
    -webkit-transform: rotate(-120deg);
    -moz-transform: rotate(-120deg);
    -o-transform: rotate(-120deg);
    -ms-transform: rotate(-120deg);
    transform: rotate(-120deg);
  }
  95% {
    -webkit-transform: rotate(20deg);
    -moz-transform: rotate(20deg);
    -o-transform: rotate(20deg);
    -ms-transform: rotate(20deg);
    transform: rotate(20deg);
  }
}

其实我来这里是想弄清楚如何在动画中放置一个延迟,当我意识到你只是 1. 延长动画的持续时间和衬衫每个动画的时间比例。Beore 我让它们每个持续 0.5 秒,总持续时间为 2.5 秒。现在假设我想添加一个等于总持续时间的延迟,因此延迟 2.5 秒。

您的动画时间为 2.5 秒,延迟为 2.5,因此您将持续时间更改为 5 秒。但是,由于您将总持续时间加倍,因此您需要将动画比例减半。检查下面的决赛。这对我来说非常有效。

@-webkit-keyframes dance {
  0% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  10% {
    -webkit-transform: rotate(20deg);
    -moz-transform: rotate(20deg);
    -o-transform: rotate(20deg);
    -ms-transform: rotate(20deg);
    transform: rotate(20deg);
  }
  20% {
    -webkit-transform: rotate(-120deg);
    -moz-transform: rotate(-120deg);
    -o-transform: rotate(-120deg);
    -ms-transform: rotate(-120deg);
    transform: rotate(-120deg);
  }
  30% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  40% {
    -webkit-transform: rotate(-120deg);
    -moz-transform: rotate(-120deg);
    -o-transform: rotate(-120deg);
    -ms-transform: rotate(-120deg);
    transform: rotate(-120deg);
  }
  50% {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
    -o-transform: rotate(0deg);
    -ms-transform: rotate(0deg);
    transform: rotate(0deg);
  }
}

总共:

这些是您可能会用来计算如何更改动画的持续时间和每个部分的百分比的计算。

所需的持续时间 = x

desired_duration = animation_part_duration1 + animation_part_duration2 + ...(以此类推)

所需延迟 = y

总持续时间 = x + y

animation_part_duration1_actual = animation_part_duration1 * desired_duration / total_duration

于 2014-01-15T07:09:46.247 回答
11

实现动画之间暂停的另一种方法是应用第二个动画,该动画隐藏元素以获得所需的延迟量。这样做的好处是允许您像往常一样使用 CSS 缓动函数。

.star {
  animation: shooting-star 1000ms ease-in-out infinite,
    delay-animation 2000ms linear infinite;
}

@keyframes shooting-star {
  0% {
    transform: translate(0, 0) rotate(45deg);
  }

  100% {
    transform: translate(300px, 300px) rotate(45deg);
  }
}

@keyframes delay-animation {
  0% {
    opacity: 1;
  }
  50% {
    opacity: 1;
  }
  50.01% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

这仅在您希望延迟是动画持续时间的倍数时才有效。我用它来让流星雨显得更随机: https ://codepen.io/ericdjohnson/pen/GRpOgVO

于 2020-05-02T19:36:38.723 回答
6

我宁愿写一点 JavaScript 而不是让 CSS 更难管理。

首先,仅在数据属性更改上应用 CSS 动画:

.progbar[data-animation="barshine"] {
    animation: barshine 1s linear;
}

然后添加javascript以延迟量的一半切换动画。

var progbar = document.querySelector('.progbar');
var on = false;

setInterval(function () {
    progbar.setAttribute('data-animation', (on) ? 'barshine' : '');
    on = !on;
}, 3000);

或者,如果您不希望在选项卡隐藏时运行动画:

var progbar = document.querySelector('.progbar');
var on = false;

var update = function () {
    progbar.setAttribute('data-animation', (on) ? 'barshine' : '');
    on = !on;
    setTimer();
};

var setTimer = function () {
    setTimeout(function () {
        requestAnimationFrame(update);
    }, 3000);
};

setTimer();
于 2015-03-23T22:59:47.100 回答
2

这是一个小片段,它在 75% 的时间里显示相同的东西,然后它会滑动。这个重复模式很好地模拟了延迟:

@-webkit-keyframes slide    {
0%   {background-position: 0 0;}
25%  {background-position: 0 0;}
50%  {background-position: 0 0;}
75%  {background-position: 0 0;}
100% {background-position: 13em 0;}
}

@-moz-keyframes slide       {
0%   {background-position: 0 0;}
25%  {background-position: 0 0;}
50%  {background-position: 0 0;}
75%  {background-position: 0 0;}
100% {background-position: 13em 0;}
}

@keyframes slide            {
0%   {background-position: 0 0;}
25%  {background-position: 0 0;}
50%  {background-position: 0 0;}
75%  {background-position: 0 0;}
100% {background-position: 13em 0;}
}
于 2015-10-28T19:50:49.710 回答
2

我在墙上做了一张海报,它有间隔地左右移动。对我来说它有效:

.div-animation {
   -webkit-animation: bounce 2000ms ease-out;
    -moz-animation: bounce 2000ms ease-out;
    -o-animation: bounce 2000ms ease-out;
    animation: bounce 2000ms ease-out infinite;
    -webkit-animation-delay: 2s; /* Chrome, Safari, Opera */
    animation-delay: 2s;
    transform-origin: 55% 10%;    
}

@-webkit-keyframes bounce {
    0% {
        transform: rotate(0deg);
    }
    3% {
        transform: rotate(1deg);
    }
    6% {
        transform: rotate(2deg);
    }
    9% {
        transform: rotate(3deg);
    }
    12% {
        transform: rotate(2deg);
    }
    15% {
        transform: rotate(1deg);
    }
    18% {
        transform: rotate(0deg);
    }
    21% {
        transform: rotate(-1deg);
    }
    24% {
        transform: rotate(-2deg);
    }
    27% {
        transform: rotate(-3deg);
    }
    30% {
        transform: rotate(-2deg);
    }
    33% {
        transform: rotate(-1deg);
    }
    36% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(0deg);
    }
}
于 2016-06-07T18:38:14.323 回答
1

您可以纯粹使用 CSS 在无限动画之间创建“假”延迟。做到这一点的方法是巧妙地定义你的关键帧动画点和你的动画持续时间速度。

例如,如果我们想为一个弹跳的球设置动画,并且我们希望每次弹跳之间有 0.5 秒到 1 秒的延迟,我们可以执行以下操作:

@keyframes bounce{
    0%{
        transform: translateY(0);
    }
    50%{
        transform: translateY(25%);
    }
    75%{
        transform: translateY(15%);
    }
    90%{
        transform: translateY(0%);
    }
    100%{
        transform: translateY(0);
    }
}

我们所做的是确保球早于 100% 回到原来的位置。在我的示例中,我以 90% 的速度执行此操作,这为我提供了大约 0.1 秒的延迟,这对我来说已经足够了。但显然对于您的情况,您可以添加更多关键帧点并更改变换值。

此外,您可以添加额外的动画持续时间来平衡关键帧动画。

例如:

 animation: bounce .5s ease-in-out infinite;

假设我们希望完整的动画在 0.5 秒内结束,但我们希望动画之间有 0.2 秒的额外延迟。

 animation: bounce .7s ease-in-out infinite;

所以我们会添加一个额外的 .2s 延迟,在我们的关键帧动画中,我们可以添加更多的百分点来填补 .2s 延迟的空白。

于 2019-12-17T18:35:12.697 回答
1

对于边框闪光:实际上非常简单:将 99% 黑色替换为 1%,例如 1% 变为蓝色,您甚至可以将其缩短,动画时间设置为 5 秒。

@keyframes myborder {
  0% {border-color: black;}
  99% {border-color:black;}
  100% {border-color: blue;}
 }
于 2020-09-21T08:13:23.963 回答
0

延迟在无限开始时只能有一次。排序延迟不适用于无限循环。为此,您必须保留关键帧动画空白示例:

@-webkit-keyframes barshine {
  10% {background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#1e5799), color-stop(100%,#7db9e8));
    }
  60% {background: -webkit-linear-gradient(top, #7db9e8 0%,#d32a2d 100%);}
}

它将动画 10% 到 60% 并等待完成 40% 以上。所以 40% 延迟到来。

查找小提琴示例

于 2015-05-21T07:43:25.447 回答
0

我知道这很旧,但我一直在这篇文章中寻找答案,而使用 jquery,您可以轻松地做到这一点,而且没有太多麻烦。只需在 css 中声明您的动画关键帧并使用您想要的属性设置类。在我的情况下,我使用了 css animate 中的 tada 动画:

.tada {
    -webkit-animation-name: tada;
    animation-name: tada;
    -webkit-animation-duration: 1.25s;
    animation-duration: 1.25s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
}

我希望动画每 10 秒运行一次,所以 jquery 只是添加了类,在 6000 毫秒(动画完成的足够时间)之后,它删除了类,4 秒后它再次添加了类,所以动画再次开始。

$(document).ready(function() {
  setInterval(function() {

    $(".bottom h2").addClass("tada");//adds the class

    setTimeout(function() {//waits 6 seconds to remove the class
      $(".bottom h2").removeClass("tada");
    }, 6000);

  }, 10000)//repeats the process every 10 seconds
});

一点都不像一个人发的那么难。

于 2019-09-04T21:36:58.807 回答