- CSS 수학 함수 지원이 늘면서 keyframes 대신 시간 tick 변수
--t로 애니메이션 상태를 계산하는 접근이 다시 실용화됨 @property --t와86400000ms길이의 루트 애니메이션을 조합하면 밀리초 단위 시간이 증가하고, 이를rotate,translate같은 속성 계산에 연결할 수 있음step()을 쓰면 8fps, 24fps, 60fps처럼 프레임 레이트를 제한할 수 있고, 브라우저 최적화 덕분에 60fps보다 높은 갱신 빈도도 보통 문제되지 않음min(),mod(),sin(),pow(),round()로 시간 값을 제한·반복·진동·완화 처리해 커스텀 easing과 위치 이동을 keyframes 없이 표현함css-doodle은@t,@T,@TS같은 축약 표현을 제공해 수학식이 많은 데모를 더 짧게 작성하고 빠르게 실험할 수 있음
시간 tick을 CSS 변수로 만들기
- 과거 접근은 CSS에서 복잡한 수학 계산을 하기 어려워 적용 범위가 제한적이었음
- 현재 CSS는
mod(),round(), 삼각함수 등 필요한 수학 함수를 지원해 시간 기반 애니메이션을 다시 시도할 수 있음 - 데모 확인에는 Experimental feature flags 활성화가 필요할 수 있음
기본 동작 방식
- JavaScript처럼 CSS가 직접 타이머를 시작할 수는 없지만, CSS Houdini API로 커스텀 변수
--t를 정의해 밀리초 단위 시간을 추적할 수 있음 - 기본 예시는
@property --t를<integer>로 선언하고,@keyframes tick에서0부터86400000까지 변화시키며,:root에86400000ms linear infinite애니메이션을 적용함 --t는 1밀리초마다1씩 증가하며 1초에는1000이 됨counter()를 사용하면 현재--t값을 화면에 표시할 수 있음rotate: calc(var(--t) * .001turn)처럼--t기반 계산을 속성에 연결하면 시간이 흐르며 값이 바뀌고 애니메이션으로 이어짐
프레임 레이트 제어
- 부드러운 애니메이션에는 60fps 갱신 빈도로 충분함
- 브라우저 렌더링 최적화가 있어 갱신 빈도가 60fps보다 높아도 보통 문제가 되지 않음
- 필요하면
animation-timing-function에 step() 을 사용해 프레임 레이트를 직접 제한할 수 있음- 8fps:
step(calc(86400000/(1000/8))) - 24fps:
step(calc(86400000/(1000/24))) - 60fps:
step(calc(86400000/(1000/60)))
- 8fps:
증가하는 시간 값을 애니메이션 값으로 바꾸기
--t값은 한 방향으로 계속 증가함angle값은360deg를 넘어도 괜찮지만, 모든 CSS 속성이 값을 순환적으로 처리하지는 않음translate: calc(var(--t) * .001px)는 박스를 계속 오른쪽으로 이동시킴-
min()으로 멈추기
- 특정 offset에 도달하자마자 멈추게 하려면 min() 을 사용할 수 있음
translate: min(270px, calc(var(--t) * .5px))는 이동 값을 270px로 제한함- 지속 시간을 정확히 제어하려면
--t자체를 제한할 수 있음 translate: calc(min(3000, var(--t)) * (270px / 3000))- 이 계산은 3초 동안 270px 이동하게 만듦
-
mod()로 반복하기
- 박스가 오른쪽으로 이동한 뒤 처음부터 다시 시작하려면 mod() 를 사용함
translate: calc(mod(var(--t)/4, 270) * 1px)로 offset을 반복시킬 수 있음
-
sin()으로 왕복 이동 만들기
- 왕복 이동은 sin() 으로 표현할 수 있음
translate: calc(sin(mod(var(--t)/135, 270)) * 135px)처럼 시간 값을 삼각함수에 연결함
커스텀 easing 함수
- CSS 수학 함수와
--t변수로cubic-bezier()로는 달성하기 어려울 수 있는 커스텀 easing을 만들 수 있음 - 먼저
--t를0과1사이 값으로 제한함--t01: calc(min(1000, var(--t)) / 1000)는 1초 동안 0에서 1로 변화함
-
ease-out-cubic
ease-out-cubic은1 - pow(1 - t, 3)계산식으로 구성됨--ease-out-cubic값을 만든 뒤translate: calc(var(--ease-out-cubic) * 270px)에 연결함
-
ease-out-elastic
ease-out-elastic은pow(2, -10t) * sin((10t - .75) * 2/3 * PI) + 1계산식으로 구성됨- 같은 방식으로
--ease-out-elastic값을 만들고translate에 곱해 270px 이동에 적용함
css-doodle로 수식 줄이기
- 수식이 복잡해질수록
var()와calc()가 코드를 읽기 어렵게 만듦 - css-doodle 최신 버전은
--t를 표현하는 @t 함수를 추가했고, 인자 안에서 간단한 수학식을 직접 받을 수 있음 rotate표현은 다음처럼 줄어듦- 기존:
rotate: calc(mod(var(--t) / 1000, 10) * 5deg) css-doodle:rotate: @t(/1000, %10, *5deg)
- 기존:
- keyframes를 작성하지 않아도 짧은 코드로 수학 기반 애니메이션을 만들 수 있음
- 매개변수를 바꾸면 새로운 결과를 빠르게 실험할 수 있음
-
@T와 @TS
@t외에 대문자 @T는 하루 시작부터의 time ticks를 나타냄- @TS는
@t(/1000)의 shorthand이며 시간을 초 단위로 추적함 - 시계 예시는 CodePen에서 볼 수 있음
- 초침:
rotate: @TS(*6, %360deg) - 분침:
rotate: @TS(/60, *6, %360deg) - 시침:
rotate: @TS(/60, /12, *6, %360deg)
-
round()로 초침 점프 만들기
- 초침을 점프하듯 움직이게 하려면 round() 를 사용할 수 있음
round()의 세 번째 매개변수는 반올림 간격을 지정함- 시계에서는 한 단계가
360 / 60 = 6deg이므로rotate: round(down, @TS(*6, %360deg), 6deg)를 사용함