6P by neo 13일전 | favorite | 댓글 1개

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 애니메이션을 만들기 위한 더 사용자 친화적인 도구가 있으면 좋겠음.