[css] 반복되는 CSS 애니메이션 지연

저는 최근에 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;
}

from80%애니메이션 길이의 80 %의 “지연”결과 정확히 동일하다.

이것은 작동하지만 다음 애니메이션의 경우 애니메이션 자체가 정확히 동일한 길이를 유지하는 동안 지연이 가변적 (특정 요소에 대해서는 일정하지만 애니메이션을 사용하는 요소간에 가변적 임)이 필요합니다.

위의 “솔루션”을 사용하면 원하는 것이 더 긴 지연 일 때 느린 애니메이션으로 끝날 것입니다.

그것은이있을 수 있나요 animation-delay아니라 단지 첫 번째보다, 모든 반복에 적용?



답변

비슷한 문제가 있었고

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

양쪽 끝에서 ‘지연’을 설명하기 위해 기간을 속 여야한다는 점이 약간 짜증이납니다.


답변

minitech는 animation-delay애니메이션이 시작되기 전 지연 을 지정하고 반복 사이의 지연 을 지정 하지 않습니다 . 사양의 편집자 초안은 잘 설명하고 설명하고이 기능에 대한 논의가 있었다 여기 이 반복 지연 기능을 제안.

JS에 해결 방법이있을 수 있지만 CSS 만 사용하여 진행률 표시 줄 플레어에 대해이 반복 지연을 가짜로 만들 수 있습니다.

flare div position:absolute및 부모 div 를 선언하고 overflow: hidden진행률 표시 줄의 너비보다 큰 100 % 키 프레임 상태를 설정하고 cubic-bezier 타이밍 함수 와 왼쪽 오프셋 값을 가지고 놀 면서 ease-in-out또는 linear타이밍을 다음과 같이 에뮬레이션 할 수 있습니다. 지연”.

이 정확한 값을 얻기 위해 왼쪽 오프셋과 타이밍 함수를 정확히 계산하기 위해 less / scss 믹스 인을 작성하는 것이 흥미로울 것입니다. 그래도 그런 걸보고 싶어요!

이것을 보여주기 위해 함께 던진 데모가 있습니다. (나는 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;
}


답변

이것이 당신이해야 할 일입니다. 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는 총 2.5 초 동안 0.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);
  }
}

요약해서 말하면:

다음은 애니메이션의 지속 시간과 각 부분의 %를 변경하는 방법을 알아내는 데 사용할 수있는 계산입니다.

desired_duration = x

desired_duration = animation_part_duration1 + animation_part_duration2 + … (등)

desired_delay = y

총 기간 = x + y

animation_part_duration1_actual = animation_part_duration1 * desired_duration / total_duration


답변

CSS를 덜 관리하기보다는 약간의 JavaScript를 작성하는 편이 낫습니다.

첫째, 데이터 속성 변경에만 CSS 애니메이션을 적용합니다.

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

그런 다음 자바 스크립트를 추가하여 지연 시간의 절반으로 애니메이션을 전환합니다.

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();


답변

간격을두고 좌우로 움직이는 벽에 포스터를 만들었습니다. 나를 위해 그것은 작동합니다.

.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);
    }
}


답변

애니메이션 사이에 일시 중지를 달성 할 수있는 또 다른 방법은 원하는 지연 시간 동안 요소를 숨기는 두 번째 애니메이션을 적용하는 것입니다. 이렇게하면 평소처럼 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


답변

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;}
}