콘텐츠로 이동

애니메이션

This content is for v0.4. Switch to the latest version for up-to-date documentation.

시간에 따라 바꿀 수 있는 값은 거의 모두 같은 방식, 즉 상수 또는 키프레임으로 씁니다. 이 페이지에서는 그 형식과 보간 곡선을 다루고, 많은 사람이 헷갈리는 한 가지, 키프레임의 time이 어떤 시계로 재는 시간인지를 설명합니다.

애니메이션할 수 있는 값은 mode가 있는 객체입니다.

{ "mode": "constant", "value": 0.5 }
{
"mode": "keyframes",
"keyframes": [
{ "time": 0, "value": 0, "interpolation": { "type": "linear" } },
{ "time": 60000, "value": 1, "interpolation": { "type": "hold" } }
]
}
  • 키프레임은 time이 엄격하게 증가하는 순서여야 합니다. 순서가 어긋난 시퀀스는 엔진이 거부합니다.
  • 첫 키프레임 이전의 값은 첫 키프레임의 값이고, 마지막 키프레임 이후의 값은 마지막 키프레임의 값입니다.
  • 키프레임의 interpolation은 그 키프레임에서 다음 키프레임까지 값이 움직이는 방식입니다. 마지막 키프레임의 보간은 쓰이지 않으므로 보통 hold를 둡니다.

값의 타입은 필드에 따라 다릅니다. 불투명도는 숫자, 위치나 크기는 { "x", "y" }, 페인트는 페인트 객체, 이펙트 파라미터는 이펙트 값({ "type": "float", "value": 0.4 }), 레이아웃 텍스트는 문자열입니다. 스키마에는 Animated_float, Animated_Vec2, Animated_EffectValue 등으로 나와 있습니다(레퍼런스).

Interpolation에는 세 가지 타입이 있습니다.

타입 다음 값으로 움직이는 방식
hold 움직이지 않습니다. 다음 키프레임에 도달하는 순간 값이 바뀝니다.
linear 일정한 속도로 움직입니다.
cubic_bezier CSS cubic-bezier(x1, y1, x2, y2) 타이밍 곡선을 따릅니다. x1과 x2는 0..1 범위이고, y1과 y2는 범위를 넘어갈 수 있습니다.

alpha2/project에는 CSS의 이름 있는 곡선이 값으로 들어 있습니다. EASING_PRESETS.ease는 cubic_bezier(0.25, 0.1, 0.25, 1)이고, easeIn, easeOut, easeInOut, linear도 있습니다. cubicBezier(x1, y1, x2, y2)와 HOLD도 제공합니다.

값은 숫자 그대로 보간됩니다. 0도에서 720도로 회전하면 두 바퀴를 돕니다. 가장 짧은 경로로 돌리고 싶다면 키프레임 값을 정규화하세요.

트랜지션에 쓰는 Easing은 hold가 없다는 점만 빼면 같습니다.

보간되지 않는 값도 있습니다.

  • enum과 bool 이펙트 파라미터는 hold만 합니다.
  • 문자열(레이아웃 텍스트)도 hold만 합니다.
  • 보간 중에 이펙트 파라미터가 범위를 넘으면 범위 안으로 잘립니다. 직접 작성한 키프레임 값이 범위를 벗어나면 오류입니다.

위치(AnimatedPoint)는 곡선을 따라 움직일 수도 있습니다. 키프레임에 out_tangent를, 다음 키프레임에 in_tangent를 주면 점이 그 둘을 지나는 3차 베지어 곡선을 따라갑니다. 이때 보간은 경로를 따라 움직이는 속도를 정합니다.

키프레임의 time은 틱 단위이지만, 값의 주인이 누구냐에 따라 기준점이 다릅니다.

주인 키프레임 기준 0이 되는 시점
클립의 visual, 마스크, 타임라인 트랜지션의 파라미터 타임라인 시간 프로젝트가 시작할 때
컴포지션 노드의 설정(이펙트 파라미터, 트랜스폼) 컴포지션 시간 클립이 시작할 때(기본값. ClipComposition 참고)
셰이프와 레이아웃 제너레이터 픽처 시간 클립이 고른 소스 시간이 0일 때

이유는 이렇습니다. 클립의 visual은 클립을 타임라인에 배치하므로 타임라인 시간으로 키프레임합니다. 컴포지션은 자신을 보여 주는 클립과 함께 움직입니다. 생성된 그림은 소스이므로, 비디오 파일과 마찬가지로 클립이 잘라서 배치합니다.

다음 프로젝트는 세 가지 시간을 모두 사용합니다.

{
"schema_version": 1,
"id": "animation",
"name": "Animation time bases",
"settings": { "width": 1280, "height": 720, "frame_rate": { "num": 30, "den": 1 }, "sample_rate": 48000 },
"sources": [
{ "id": "boathouse", "kind": "image", "locator": "asset://boathouse" },
{
"id": "dot",
"kind": "generated",
"generator": {
"type": "shapes",
"items": [
{
"type": "ellipse",
"center": {
"mode": "keyframes",
"keyframes": [
{
"time": 0,
"value": { "x": 0.15, "y": 0.8 },
"interpolation": { "type": "cubic_bezier", "x1": 0.25, "y1": 0.1, "x2": 0.25, "y2": 1 }
},
{
"time": 240000,
"value": { "x": 0.85, "y": 0.8 },
"interpolation": { "type": "hold" }
}
]
},
"size": { "mode": "constant", "value": { "x": 0.06, "y": 0.1067 } }
},
{
"type": "fill",
"paint": {
"mode": "constant",
"value": { "type": "solid", "color": { "red": 1, "green": 0.7, "blue": 0.1, "alpha": 1 } }
}
}
]
}
}
],
"compositions": [
{
"id": "focus",
"nodes": [
{ "id": "picture", "op": { "type": "clip" } },
{
"id": "blur",
"op": {
"type": "effect",
"input": "picture",
"effect": {
"id": "alpha2.effect.gaussian-blur",
"version": 1,
"params": {
"radius": {
"mode": "keyframes",
"keyframes": [
{
"time": 0,
"value": { "type": "float", "value": 0.03 },
"interpolation": { "type": "linear" }
},
{
"time": 120000,
"value": { "type": "float", "value": 0 },
"interpolation": { "type": "hold" }
}
]
}
}
}
}
}
],
"output": "blur"
}
],
"timeline": {
"tracks": [
{
"id": "picture",
"name": "Picture",
"kind": "video",
"clips": [
{
"id": "photo",
"source_id": "boathouse",
"timeline_range": { "start": 0, "end": 480000 },
"source_range": { "start": 0, "end": 480000 },
"composition": { "id": "focus" },
"visual": {
"scale": {
"mode": "keyframes",
"keyframes": [
{
"time": 0,
"value": { "x": 1, "y": 1 },
"interpolation": { "type": "linear" }
},
{
"time": 480000,
"value": { "x": 1.15, "y": 1.15 },
"interpolation": { "type": "hold" }
}
]
},
"opacity": {
"mode": "keyframes",
"keyframes": [
{
"time": 0,
"value": 0,
"interpolation": { "type": "cubic_bezier", "x1": 0.25, "y1": 0.1, "x2": 0.25, "y2": 1 }
},
{ "time": 60000, "value": 1, "interpolation": { "type": "hold" } }
]
}
}
}
]
},
{
"id": "overlay",
"name": "Overlay",
"kind": "video",
"clips": [
{
"id": "dot-clip",
"source_id": "dot",
"timeline_range": { "start": 120000, "end": 420000 },
"source_range": { "start": 0, "end": 300000 }
}
]
}
]
}
}
  • 사진의 visual.opacity와 visual.scale은 타임라인 시간으로 키프레임되어 있습니다. 페이드인은 프로젝트의 0초부터 0.5초까지, 천천히 확대되는 줌은 4초 전체에 걸쳐 진행됩니다.
  • focus 컴포지션의 블러 radius는 컴포지션 시간으로 키프레임되어 있어서, 클립의 첫 1초 동안 블러가 걷힙니다.
  • 점의 center는 dot 소스의 픽처 시간 0초부터 2초까지 키프레임되어 있습니다. 클립이 이 그림을 타임라인 1초 지점에 놓으므로 점은 1초에 움직이기 시작해 3초에 멈춥니다.

셰이프 프리셋은 타원의 중심을 픽처 시간으로 키프레임하므로, 클립의 3초 동안 타원이 가로질러 움직입니다.