CSS 전용 Wolfenstein 몇 주 전에 만든 작은 프로젝트입니다. CSS 3D 변형과 애니메이션에 대한 실험이었습니다.
에 의해 영감을 FPS 데모 다른 Wolfenstein 코드펜, 나는 내 자신의 버전을 만들기로 결정했습니다. 원래 Wolfenstein 1D 게임의 에피소드 9 – 플로어 3를 기반으로 합니다.
편집자: 이 게임은 게임 오버 화면을 피하기 위해 의도적으로 약간의 빠른 반응이 필요합니다.
재생 동영상은 다음과 같습니다.
간단히 말해서, 내 프로젝트는 신중하게 스크립트된 긴 CSS 애니메이션에 불과합니다. 또한 몇 가지 사례 체크박스 해킹.
:checked ~ div { animation-name: spin; }
환경은 3D 그리드 면으로 구성되며 애니메이션은 대부분 일반 3D 변환 및 회전입니다. 정말 멋진 것은 없습니다.
그러나 두 가지 문제는 특히 해결하기 어려웠습니다.
- 플레이어가 적을 클릭할 때마다 "무기 발사" 애니메이션을 재생합니다.
- 빠르게 움직이는 보스가 마지막 타격을 받으면 극적인 슬로우 모션을 입력하십시오.
기술 수준에서 이것은 다음을 의미했습니다.
- 다음 확인란이 선택되면 애니메이션을 재생합니다.
- 확인란을 선택하면 애니메이션 속도가 느려집니다.
사실, 내 프로젝트에서 둘 다 제대로 해결되지 않았습니다! 해결 방법을 사용하거나 그냥 포기했습니다.
반면에, 약간의 파기 끝에 결국 두 문제의 핵심을 찾았습니다. 바로 실행 중인 CSS 애니메이션의 속성을 변경하는 것입니다. 이 기사에서는 이 주제에 대해 더 자세히 알아볼 것입니다.
- 많은 대화식 예제.
- 해부: 각 예제는 어떻게 작동합니까(또는 작동하지 않음)?
- 비하인드 스토리: 브라우저는 애니메이션 상태를 어떻게 처리합니까?
내게 알려줘. "내 벽돌을 던져".
문제 1: 애니메이션 재생
첫 번째 예: "또 다른 확인란"
내 첫 번째 직감은 작동하지 않는 "다른 확인란을 추가하십시오"였습니다.
각 확인란은 개별적으로 작동하지만 함께 작동하지는 않습니다. 하나의 확인란이 이미 선택되어 있으면 다른 하나는 더 이상 작동하지 않습니다.
작동 방식(또는 "작동하지 않음")은 다음과 같습니다.
- XNUMXD덴탈의
animation-name
of<div>
isnone
기본적으로 - 사용자가 하나의 확인란을 클릭하면
animation-name
된다spin
, 애니메이션이 처음부터 시작됩니다. - 잠시 후 사용자가 다른 확인란을 클릭합니다. 새로운 CSS 규칙이 적용되지만
animation-name
is 여전히spin
, 즉 애니메이션이 추가되거나 제거되지 않습니다. 애니메이션은 아무 일도 없었던 것처럼 계속 재생됩니다.
두 번째 예: "애니메이션 복제"
한 가지 작업 접근 방식은 애니메이션을 복제하는 것입니다.
#spin1:checked ~ div { animation-name: spin1; }
#spin2:checked ~ div { animation-name: spin2; }
사용하는 방법은 다음과 같습니다
animation-name
isnone
처음에는- 사용자가 "회전!"을 클릭하면,
animation-name
된다spin1
. 애니메이션spin1
은(는) 방금 추가되었기 때문에 처음부터 시작됩니다. - 사용자가 "다시 회전!"을 클릭하면
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
isnone
기본적으로 "애니메이션이 재생되지 않으면 아무런 효과가 없습니다"를 의미합니다.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-*
속성이 변경됩니다. 특히 "애니메이션 재생"과 "애니메이션 슬로우모션"에 대한 솔루션을 마련했습니다.
이 기사가 흥미로웠으면 합니다. 당신의 생각을 저에게 말 해주세요!