GN⁺: 시간 기반 CSS 애니메이션 기술
(yuanchuan.dev)CSS 애니메이션을 위한 시간 기반 방식 활용
- CSS에서 수학 함수들이 지원되면서, 시간 기반 방식의 CSS 애니메이션을 다시 적용해볼 수 있게 됨
- mod(), round(), 삼각함수 등이 지원됨
- 데모를 보기 위해서는 실험적 기능 플래그를 활성화해야 할 수 있음
기본 아이디어
- CSS Houdini API를 사용하여 시간(밀리초)을 추적하는 사용자 정의 변수를 정의할 수 있음
-
@property
규칙을 사용하여--t
변수를 정의하고, 초기값을 0으로 설정 -
@keyframes
규칙을 사용하여--t
변수를 24시간(86,400,000ms) 동안 선형적으로 증가시킴 -
--t
를 기반으로 하는 다른 값들은 함께 변경되어 애니메이션 효과를 만듦 -
counter()
함수를 사용하여--t
변수의 값을 표시할 수 있음
-
프레임 속도 제어
- 초당 60 프레임(FPS)의 업데이트 주기를 유지하는 것으로 부드러운 애니메이션에 충분함
- 필요한 경우
step()
함수를 사용하여 프레임 속도를 수동으로 제어할 수 있음-
animation-timing-function
속성에서step()
함수를 사용하여 원하는 FPS 값을 계산
-
시간 변환
-
--t
값은 한 방향으로 지속적으로 증가하므로, 일부 CSS 속성에는 적합하지 않을 수 있음 -
min()
함수를 사용하여 특정 값에 도달하면 애니메이션을 멈출 수 있음 -
mod()
함수를 사용하여 애니메이션을 다시 시작할 수 있음 -
sin()
함수를 사용하여 앞뒤로 움직이는 효과를 만들 수 있음
사용자 정의 Easing 함수
- 수학 함수와
--t
변수를 사용하여 사용자 정의 easing 함수를 만들 수 있음 -
cubic-bezier()
로는 달성하기 어려운 효과를 만들 수 있음 - 예시: ease-out-cubic, ease-out-elastic 등
CSS Doodle 실험
- 복잡한 표현식에서
var()
와calc()
는 코드의 가독성을 떨어뜨릴 수 있음 - css-doodle에서는
@t
함수를 사용하여--t
변수를 나타낼 수 있음 - 최신 버전의 css-doodle은 인수 내부에서 간단한 수학 표현식을 직접 허용함
-
@T
와@TS
함수도 추가로 제공됨-
@T
는 하루의 시작부터 시간을 나타냄 -
@TS
는@t(/1000)
의 단축형으로, 초 단위로 시간을 추적함
-
- 시계 예제와 점프 모션 예제 등을 css-doodle로 구현할 수 있음
결론
- 시간을 변수로 사용하는 이 접근 방식은 흥미로움
- Keyframes를 사용하는 것이 더 직관적일 수 있지만, 수학 계산과 입력 변수가 많은 데모 장면에서는 시간을 변수로 사용하는 것이 다양한 결과를 얻을 수 있음
GN⁺의 의견
- CSS의 시간 기반 애니메이션 기법은 단순히 CSS로 구현 가능한 애니메이션의 폭을 넓힐 뿐만 아니라, 쉐이더나 WebGL 등 다른 기술과의 연계 활용 가능성도 높여줄 것으로 보임
- CSS Houdini와 CSS Doodle 등의 도구와 함께 사용하면 더욱 유연하고 다양한 표현이 가능할 것 같음
- 다만 브라우저 호환성 문제나 성능 이슈 등 실제 프로젝트에 적용할 때 고려해야 할 사항들이 있을 것임. 기존의 Keyframe 방식과 장단점을 잘 비교하여 선택적으로 사용하는 것이 좋겠음
- GSAP 등 전문 애니메이션 라이브러리와 비교했을 때의 장단점도 분석해볼 필요가 있음. 상호 보완적으로 사용할 수 있는 방안을 모색해보는 것도 좋을 듯함
- 시간 기반 CSS 애니메이션의 예제와 활용 사례들이 더 많이 공유되어, 프런트엔드 개발자들이 좀 더 쉽게 적용해볼 수 있게 되기를 기대함
Hacker News 의견
-
CSS에서 음수 animation-delay 값을 사용하여 JavaScript로 애니메이션 진행을 제어할 수 있음. 예를 들어
animation-delay: -1500ms
로 설정하면 즉시 시작하되 1.5초 지점으로 건너뜀. JavaScript로 이 값을 조작하여 CSS 애니메이션을 스크러빙하고, 모든 애니메이션을 게임 엔진 스타일의 계산-업데이트-렌더링 틱 루프와 호환되게 만들 수 있음. -
간단한 easing 함수나 한두 개 채널의 기본 키프레임 이상으로 발전하면 이 접근 방식의 한계에 빠르게 직면하게 됨. Theatre.js 라이브러리를 사용하면 키프레임과 베지어 곡선을 편집하기 위한 타임라인이 있는 스튜디오 UI와 이러한 키프레임을 가져와 타임라인과 관련하여 값을 보간하는 런타임으로 구성되어 있어 조정된 애니메이션이 필요할 때 유용함.
-
이 글에서는 브라우저 지원률이 88%인 사용자 정의 CSS
@property
를 활용함. 브라우저마다 초기값 설정 방식이 다른 점은 주의해야 함. 크롬은 정의되지 않았거나 유효하지 않은 값이면 초기값을 사용하지만, 파이어폭스는 정의되지 않은 경우에만 초기값을 사용함. 대부분의 프로젝트에는 문제가 되지 않겠지만, 브라우저 간 구현 불일치를 해결하려면 JavaScript로 파이어폭스의 기본값을 설정해야 할 수도 있음. -
CSS에는
mod()
,round()
, 삼각 함수 등 충분한 수학 함수가 지원됨. CSS는 JavaScript처럼 타이머를 시작할 순 없지만, 요즘은 CSS Houdini API로 사용자 정의 변수를 정의하여 밀리초 단위로 시간을 추적할 수 있음. 그런데 JavaScript가 있는데 왜 이런 것들이 모두 필요할까? 그리기 레이어는 그리기 프리미티브에만 관심을 가져야 하지 않을까? 왜 고차원 레이어를 점점 더 많이 넣으려 하는 걸까? -
만든 시계가 매우 세련되어 보임. 잘 작성된 글임. 크롬은 아직
mod()
에 대한 CSS 지원을 출시하지 않아서 미리 보기 릴리스를 사용하지 않으면 페이지의 대부분 예제가 애니메이션되지 않음. -
틱을 제어할 필요 없이 모든 브라우저에서 부드러운 CSS 애니메이션을 원한다면 FLIP 방법이 유용함.
-
들숨-멈춤-날숨-멈춤 단계를 모두 사용자 정의하여 자신의 신체에 맞추고 원하는 효과를 낼 수 있는 '박스 호흡' 같은 것을 하고 싶었는데, 이 페이지에 있는 것 같은 방법 없이는 (JS나 엄청난 복잡성 없이는) 할 방법을 찾지 못했음. 이 페이지에는 정말 창의적인 데모가 있음!
-
흥미롭게도
mod()
를 사용하기 전의 데모는 작동하지만mod()
와sin()
은 최신 안드로이드 크롬에서 아무 작업도 하지 않음. -
페이지 하단의 애니메이션이 매우 인상적임. <div> 요소가 아닌 <video>처럼 보임.
-
매우 인상적이지만, 어떻게 보면 수십 년 전 플래시로 할 수 있었던 것에 가까운 지점에 도달한 것 같음. 플래시가 다시 돌아오길 바라지는 않지만 CSS 애니메이션을 만들기 위한 더 사용자 친화적인 도구가 있으면 좋겠음.