CSS 애니메이션 상태 및 재생 시간 해킹 PlatoBlockchain 데이터 인텔리전스. 수직 검색. 일체 포함.

CSS 애니메이션 상태 및 재생 시간 해킹

CSS 전용 Wolfenstein 몇 주 전에 만든 작은 프로젝트입니다. CSS 3D 변형과 애니메이션에 대한 실험이었습니다.

에 의해 영감을 FPS 데모 다른 Wolfenstein 코드펜, 나는 내 자신의 버전을 만들기로 결정했습니다. 원래 Wolfenstein 1D 게임의 에피소드 9 – 플로어 3를 기반으로 합니다.

편집자: 이 게임은 게임 오버 화면을 피하기 위해 의도적으로 약간의 빠른 반응이 필요합니다.

재생 동영상은 다음과 같습니다.

[포함 된 콘텐츠]

간단히 말해서, 내 프로젝트는 신중하게 스크립트된 긴 CSS 애니메이션에 불과합니다. 또한 몇 가지 사례 체크박스 해킹.

:checked ~ div { animation-name: spin; }

환경은 3D 그리드 면으로 구성되며 애니메이션은 대부분 일반 3D 변환 및 회전입니다. 정말 멋진 것은 없습니다.

그러나 두 가지 문제는 특히 해결하기 어려웠습니다.

  • 플레이어가 적을 클릭할 때마다 "무기 발사" 애니메이션을 재생합니다.
  • 빠르게 움직이는 보스가 마지막 타격을 받으면 극적인 슬로우 모션을 입력하십시오.

기술 수준에서 이것은 다음을 의미했습니다.

  • 다음 확인란이 선택되면 애니메이션을 재생합니다.
  • 확인란을 선택하면 애니메이션 속도가 느려집니다.

사실, 내 프로젝트에서 둘 다 제대로 해결되지 않았습니다! 해결 방법을 사용하거나 그냥 포기했습니다.

반면에, 약간의 파기 끝에 결국 두 문제의 핵심을 찾았습니다. 바로 실행 중인 CSS 애니메이션의 속성을 변경하는 것입니다. 이 기사에서는 이 주제에 대해 더 자세히 알아볼 것입니다.

  • 많은 대화식 예제.
  • 해부: 각 예제는 어떻게 작동합니까(또는 작동하지 않음)?
  • 비하인드 스토리: 브라우저는 애니메이션 상태를 어떻게 처리합니까?

내게 알려줘. "내 벽돌을 던져".

문제 1: 애니메이션 재생

첫 번째 예: "또 다른 확인란"

내 첫 번째 직감은 작동하지 않는 "다른 확인란을 추가하십시오"였습니다.

각 확인란은 개별적으로 작동하지만 함께 작동하지는 않습니다. 하나의 확인란이 이미 선택되어 있으면 다른 하나는 더 이상 작동하지 않습니다.

작동 방식(또는 "작동하지 않음")은 다음과 같습니다.

  1. XNUMXD덴탈의 animation-name of <div> is none 기본적으로
  2. 사용자가 하나의 확인란을 클릭하면 animation-name 된다 spin, 애니메이션이 처음부터 시작됩니다.
  3. 잠시 후 사용자가 다른 확인란을 클릭합니다. 새로운 CSS 규칙이 적용되지만 animation-name is 여전히 spin, 즉 애니메이션이 추가되거나 제거되지 않습니다. 애니메이션은 아무 일도 없었던 것처럼 계속 재생됩니다.

두 번째 예: "애니메이션 복제"

한 가지 작업 접근 방식은 애니메이션을 복제하는 것입니다.

#spin1:checked ~ div { animation-name: spin1; }
#spin2:checked ~ div { animation-name: spin2; }

사용하는 방법은 다음과 같습니다

  1. animation-name is none 처음에는
  2. 사용자가 "회전!"을 클릭하면, animation-name 된다 spin1. 애니메이션 spin1 은(는) 방금 추가되었기 때문에 처음부터 시작됩니다.
  3. 사용자가 "다시 회전!"을 클릭하면 animation-name 된다 spin2. 애니메이션 spin2 은(는) 방금 추가되었기 때문에 처음부터 시작됩니다.

3단계에서, spin1 CSS 규칙의 순서 때문에 제거되었습니다. "다시 회전!"하면 작동하지 않습니다. 먼저 확인됩니다.

세 번째 예: "동일한 애니메이션 추가"

또 다른 작업 접근 방식은 "동일한 애니메이션 추가"입니다.

#spin1:checked ~ div { animation-name: spin; }
#spin2:checked ~ div { animation-name: spin, spin; }

이는 이전 예와 유사합니다. 실제로 다음과 같은 방식으로 동작을 이해할 수 있습니다.

#spin1:checked ~ div { animation-name: spin1; }
#spin2:checked ~ div { animation-name: spin2, spin1; }

"다시 회전!"할 때 주의하십시오. 를 선택하면 이전 실행 애니메이션이 새 목록의 두 번째 애니메이션이 되어 직관적이지 않을 수 있습니다. 직접적인 결과는 다음과 같습니다. animation-fill-mode is forwards. 데모는 다음과 같습니다.

이것이 왜 그런지 궁금하다면 다음과 같은 몇 가지 단서가 있습니다.

  • animation-fill-mode is none 기본적으로 "애니메이션이 재생되지 않으면 아무런 효과가 없습니다"를 의미합니다.
  • animation-fill-mode: forwards; "애니메이션 재생이 끝나면 마지막 키프레임에 영원히 남아 있어야 합니다"를 의미합니다.
  • spin1의 결정은 항상 무시됩니다. spin2때문에 spin1 나중에 목록에 나타납니다.
  • 사용자가 "Spin!"을 클릭하고 완전히 회전할 때까지 기다린 다음 "Spin again!"을 클릭한다고 가정합니다. 지금이 순간. spin1 이미 완료되었으며 spin2 그냥 시작합니다.

토론

경험에 따르면 기존 CSS 애니메이션을 "다시 시작"할 수 없습니다. 대신 새 애니메이션을 추가하고 재생하려고 합니다. 이것은 다음과 같이 확인할 수 있습니다. W3C 사양:

애니메이션이 시작되면 종료되거나 animation-name이 제거될 때까지 계속됩니다.

이제 마지막 두 예를 비교하면서 실제로 "애니메이션 복제"가 더 잘 작동해야 하는 경우가 많습니다. 특히 CSS 전처리기를 사용할 수 있을 때 그렇습니다.

문제 2: 슬로우 모션

애니메이션을 느리게 하는 것은 단순히 더 길게 설정하는 문제라고 생각할 수도 있습니다. animation-duration:

div { animation-duration: 0.5s; }
#slowmo:checked ~ div { animation-duration: 1.5s; }

실제로 다음과 같이 작동합니다.

... 아니면 합니까?

몇 가지 조정으로 문제를 더 쉽게 볼 수 있습니다.

예, 애니메이션이 느려집니다. 그리고 아니요, 잘 보이지 않습니다. 확인란을 토글하면 개는 (거의) 항상 "점프"합니다. 게다가 개는 초기 위치가 아닌 임의의 위치로 점프하는 것처럼 보입니다. 어때요?

두 개의 "그림자 요소"를 도입하면 더 쉽게 이해할 수 있습니다.

두 그림자 요소는 서로 다른 animation-duration. 그리고 체크박스의 영향을 받지 않습니다.

확인란을 토글하면 요소가 두 그림자 요소의 상태 사이를 즉시 전환합니다.

인용 W3C 사양:

애니메이션이 실행되는 동안 애니메이션 속성 값에 대한 변경 사항은 애니메이션이 시작될 때부터 해당 값이 있었던 것처럼 적용됩니다.

이것은 다음을 따른다. 무국적자 브라우저가 애니메이션 값을 쉽게 결정할 수 있도록 하는 디자인. 실제 계산이 설명되어 있습니다. 여기에서 지금 확인해 보세요.여기에서 지금 확인해 보세요..

또 다른 시도

한 가지 아이디어는 현재 애니메이션을 일시 중지한 다음 거기에서 인계되는 더 느린 애니메이션을 추가하는 것입니다.

div {
  animation-name: spin1;
  animation-duration: 2s;
}

#slowmo:checked ~ div {
  animation-name: spin1, spin2;
  animation-duration: 2s, 5s;
  animation-play-state: paused, running;
}

그래서 그것은 작동합니다 :

... 아니면 합니까?

"Slowmo!"를 클릭하면 속도가 느려집니다. 그러나 완전한 원을 기다리면 "점프"가 표시됩니다. 실제로는 항상 "Slowmo!" 가 클릭됩니다.

그 이유는 우리가 가지고 있지 않기 때문입니다. from 키프레임이 정의되어 있으며 그렇게 해서는 안 됩니다. 사용자가 "Slowmo!"를 클릭하면, spin1 어떤 위치에서 일시 중지되고 spin2 정확히 같은 위치에서 시작합니다. 우리는 단순히 그 위치를 미리 예측할 수 없습니다 ... 아니면 우리가 할 수 있습니까?

작동 솔루션

우리는 할 수 있습니다! 사용자 정의 속성을 사용하여 첫 번째 애니메이션에서 각도를 캡처한 다음 두 번째 애니메이션으로 전달할 수 있습니다.

div {
  transform: rotate(var(--angle1));
  animation-name: spin1;
  animation-duration: 2s;
}

#slowmo:checked ~ div {
  transform: rotate(var(--angle2));
  animation-name: spin1, spin2;
  animation-duration: 2s, 5s;
  animation-play-state: paused, running;
}

@keyframes spin1 {
  to {
    --angle1: 360deg;
  }
}

@keyframes spin2 {
  from {
    --angle2: var(--angle1);
  }
  to {
    --angle2: calc(var(--angle1) + 360deg);
  }
}

참고 : @property 이 예에서는 다음과 같이 사용됩니다. 모든 브라우저에서 지원되지 않음.

"완벽한" 솔루션

이전 솔루션에 대한 경고가 있습니다. "Slowmo 종료"가 제대로 작동하지 않습니다.

더 나은 솔루션은 다음과 같습니다.

이 버전에서는 슬로우 모션을 원활하게 입력하거나 종료할 수 있습니다. 실험 기능도 사용되지 않습니다. 그렇다면 완벽한 솔루션일까요? 예, 아니요.

이 솔루션은 "변속" "기어"처럼 작동합니다.

  • 기어: 두 가지가 있습니다. <div>에스. 하나는 다른 하나의 부모입니다. 둘 다 가지고 spin 애니메이션이지만 다른 animation-duration. 요소의 최종 상태는 두 애니메이션의 누적입니다.
  • Shifting: 처음에는 하나만 <div> 애니메이션이 실행 중입니다. 다른 하나는 일시 중지됩니다. 확인란이 토글되면 두 애니메이션 모두 상태를 바꿉니다.

결과가 정말 마음에 들긴 하지만 한 가지 문제가 있습니다. spin 일반적으로 다른 유형의 애니메이션에서는 작동하지 않는 애니메이션입니다.

실용적인 솔루션(JS 포함)

일반 애니메이션의 경우 약간의 JavaScript로 슬로우 모션 기능을 구현할 수 있습니다.

간단한 설명 :

  • 사용자 정의 속성은 애니메이션 진행 상황을 추적하는 데 사용됩니다.
  • 확인란을 토글하면 애니메이션이 "다시 시작"됩니다.
  • JS 코드는 올바른 animation-delay 원활한 전환을 보장합니다. 나는 추천한다 이 문서 음수 값에 익숙하지 않은 경우 animation-delay.

이 솔루션을 "애니메이션 재시작"과 "기어 변속" 접근 방식의 하이브리드로 볼 수 있습니다.

여기서 애니메이션 진행 상황을 올바르게 추적하는 것이 중요합니다. 해결 방법은 다음과 같은 경우 가능합니다. @property 사용할 수 없습니다. 예를 들어 이 버전은 다음을 사용합니다. z-index 진행 상황을 추적하려면:

참고: 원래 CSS 전용 버전도 만들려고 했지만 성공하지 못했습니다. 100% 확신할 수는 없지만, animation-delay is 애니메이션 불가능.

다음은 JavaScript가 최소화된 버전입니다. "슬로우모션 진입"만 작동합니다.

작동하는 CSS 전용 버전을 만들 수 있는지 알려주세요!

슬로우 모션 모든 애니메이션(JS 포함)

마지막으로 여러 복잡한 애니메이션이 있는 경우에도 (거의) 모든 애니메이션에서 작동하는 솔루션을 공유하고 싶습니다. @keyframes:

기본적으로 애니메이션 진행률 추적기를 추가한 다음 신중하게 계산해야 합니다. animation-delay 새로운 애니메이션을 위해. 그러나 때로는 올바른 값을 얻는 것이 까다로울 수 있지만 가능합니다.

예 :

  • animation-timing-function 하지 않습니다 linear.
  • animation-direction 하지 않습니다 normal.
  • 여러 값 animation-name 다른과 animation-duration'모래 animation-delay'에스.

이 방법도 설명되어 있습니다 여기에서 지금 확인해 보세요. 위한 웹 애니메이션 API.

감사의

CSS 전용 프로젝트를 만난 후 이 경로를 시작했습니다. 일부는 섬세한 작품, 그리고 일부는 복잡한 장치. 내가 가장 좋아하는 것은 3D 개체와 관련된 것입니다. 예를 들어, 튀는 공패킹 큐브.

처음에는 이것들이 어떻게 만들어졌는지 전혀 몰랐습니다. 나중에 나는 많은 것을 읽고 배웠다. Ana Tudor의 이 멋진 튜토리얼.

결과적으로 CSS로 3D 개체를 만들고 애니메이션하는 것은 CSS로 하는 것과 크게 다르지 않습니다. 믹서기, 약간 다른 맛으로.

결론

이 기사에서는 CSS 애니메이션의 동작을 조사했습니다. animate-* 속성이 변경됩니다. 특히 "애니메이션 재생"과 "애니메이션 슬로우모션"에 대한 솔루션을 마련했습니다.

이 기사가 흥미로웠으면 합니다. 당신의 생각을 저에게 말 해주세요!

타임 스탬프 :

더보기 CSS 트릭