Animations
Animations in iLoveVideoEditor are keyframe-based. Each animation targets a single property and runs between keyframes expressed in source seconds.
You can also build and preview animations visually in the Studio without writing any code.
Animation model
type Animation = {
id: string;
property: string;
keyframes: Keyframe[];
easing?: Easing;
};
type Keyframe = {
time: number; // source seconds
value: unknown;
easing?: Easing;
};Easing can be one of:
step— hold value until next keyframelinear— constant speedeaseIn— accelerateeaseOut— decelerateeaseInOut— slow at both ends
Using animate()
The fluent API hides the raw keyframe structure. layer.animate(from, to, options) creates two keyframes at time: 0 and time: duration.
bg.animate(
{ opacity: 0 },
{ opacity: 1 },
{ duration: '1s', easing: 'easeOut', wait: false },
);| Option | Description |
|---|---|
duration | Length of the animation (any Time format) |
easing | Default easing between the two keyframes |
wait | If false, the flow pointer continues immediately |
Chaining animations
Multiple .animate() calls on the same layer produce separate Animation entries.
const text = $.addText({ text: 'Bounce', fontSize: 6 });
text.animate({ position: [0.5, 0.4] }, { position: [0.5, 0.6] }, { duration: '1s', wait: false });
text.animate({ position: [0.5, 0.6] }, { position: [0.5, 0.4] }, { duration: '1s', wait: false });Parallel animations
Run unrelated animations at the same time:
$.parallel([
() => { text.animate({ opacity: 0 }, { opacity: 1 }, { duration: '1s' }); },
() => { bg.animate({ scale: 1 }, { scale: 1.1 }, { duration: '1s' }); },
]);Animating multiple properties
from and to can contain any number of properties:
text.animate(
{ opacity: 0, scale: 0.8, rotation: -10 },
{ opacity: 1, scale: 1, rotation: 0 },
{ duration: '800ms', easing: 'easeOut' },
);Animating effect parameters
Use dot-path notation to animate the parameter of an effect declared on the layer:
$.addText(
{
text: 'Pulse',
effects: [{ effect: 'glow', params: { intensity: 0, radius: 1, color: '#ff5a1f' } }],
},
{ sourceDuration: 5 },
).animate(
{ 'effects.glow.intensity': 0 },
{ 'effects.glow.intensity': 1.5 },
{ duration: '1s', wait: false, easing: 'easeOut' },
);The path is effects.<effectName>.<param>. It always targets the first effect with that name on the layer.
Manual keyframes
When building raw VideoJSON, you can attach animations directly:
{
"type": "text",
"animations": [
{
"id": "anim-1",
"property": "opacity",
"keyframes": [
{ "time": 0, "value": 0 },
{ "time": 1, "value": 1, "easing": "easeOut" }
]
}
]
}Time base
Keyframe time is measured in source seconds, not timeline seconds. For non-media layers this is the elapsed time since the layer started. For media layers, it is the absolute time inside the source clip.
If you change speed, the keyframe timing is stretched automatically.