How to keyframe AI animation: spans, not points
Point keyframes only mean something beside their neighbors. When an AI reads your timing, a span — start, end, what changes — stands alone. How to write them.
5 min read
Keyframe animation is the technique where you define the moments that matter — the keyframes — and the software fills in everything between them. That definition has held since hand-drawn animation, and every editor you have used implements it the same way: a keyframe is a point, a single value pinned to a single frame.
Put an AI anywhere in that chain — generating the animation, generating the video the animation sits over, or writing the first pass of the keyframes themselves — and the point model starts failing in a specific, predictable way. This post is about the shape that replaces it, and how to author it.
What a point keyframe can't say
"Opacity is 1 at frame 30" sounds like an instruction, but it only means anything next to its neighbor. Is that a fade-in? From what? Starting when? The point borrows all of its meaning from the keyframe before it — which is fine while a human is placing both, because the intent lives in your head.
Ask a model to produce keyframes in that format and the intent has nowhere to live. We know because we tried: generated plans came back as piles of single-property points — an opacity here, a scale there — with nothing anywhere describing the shot. Each point was technically valid and the set was unusable, because the thing that made them a fade or a push-in was exactly what the format could not hold.
A span stands alone
The fix is to make the keyframe carry its own context. A span has a start and an end in seconds, a description of what happens across it, and for each animated property an explicit from and to:
[0:00–0:03] opacity 0 → 1— a fade-in, complete in itself. No neighbor required to decode it.[0:02–0:06] scale 1 → 1.15, "slow push toward the lighthouse"— the numbers for a renderer, the sentence for anything that reads intent.[0:05–0:08] "the beam sweeps once across frame"— no properties at all, and still actionable, because a description is a first-class part of the span rather than a comment.
That last variant is the important one. A renderer interpolates the numbers and ignores the prose; a video generator reads the prose and ignores nothing. One format, both consumers — which is what lets the same track drive a deterministic render and a generated clip's pacing without being retyped for either.
The interpolation rules worth knowing
Spans still interpolate — each property ramps from its from to its to across the span's duration. Three behaviors around the edges are worth internalizing, because they are where animations quietly go wrong:
- A property holds its last value outside the spans that name it. Fade something in over the first three seconds and it stays visible afterwards — you do not need a second span pinning opacity at 1 for the rest of the clip.
- Colors ramp too.
colorandbackgroundColorinterpolate between CSS colors like the numeric properties do, so a background can move from navy to black across a span rather than cutting. - A value that can't interpolate steps instead of breaking. An unparseable color, or any non-numeric value, holds at its most recent keyframe rather than taking the render down. Degraded output beats no output — but it means a typo shows up as a jump cut, not an error message.
Let a model write the first pass
Once keyframes carry descriptions, generating them becomes reasonable. Describe the shot — "product floats in, label comes into focus, settles centered" — and a model can return spans: description-led, with numeric properties only where the action actually maps onto one. A "comes into focus" span gets an opacity ramp; "the dolphin leaps toward the boat" stays prose, because inventing fake numbers for it would only mislead the renderer.
The generated rows land as ordinary editable state, not a sealed result. That matters more than the generation does: the model gets you a structurally sound first pass in seconds, and then every timing is draggable and every description rewritable. Treat generated keyframes the way you treat generated copy — a draft you own from the moment it arrives.
In QueyFrames this is the keyframes port on the llm node and the build button on the render node. Wire the result onward and the consuming node's own editor goes read-only while the wire is attached — the track has one author at a time — and hand editing resumes the moment you disconnect.
Marks are the other half
Not every timing is a span. The end of a chorus, a cut point, the moment a door slams — those are instants: a name and a number of milliseconds into the media. They come from wherever they genuinely originate — sections marked on a waveform, the boundaries a music generator publishes, marks dropped on a timeline ruler — and they stay in sync with the audio because nobody retyped them.
The two shapes convert cleanly in one direction: wire n marks into an animation and they re-cut its spans into n − 1 of them, each starting and ending on a real instant, keeping the descriptions and properties it already had. That is the whole workflow for cutting motion to music — the beats arrive as marks, the animation re-times to them, and when the track changes the marks move and the spans follow.
The short version
- Author spans, not points — a start, an end, and what changes between them, so each keyframe stands alone.
- Give every span a description. Renderers ignore it; everything AI-shaped depends on it.
- Lean on the hold rule instead of pinning values with extra keyframes.
- Generate the first pass from a shot description, then edit it like the draft it is.
- Keep instants as marks, and let them re-cut the spans rather than typing the same numbers twice.
For what a keyframe means across a whole project — one timing every node reads — see keyframes as shared timing. For how spans end up in the sentence a video model actually reads, see prompts that control pacing.
Keep reading
- 5 min read
How to write AI video prompts that control pacing
Text-to-video models will give you the shot and invent the timing. Here is how to write the timing into the prompt — naming beats in order, pinning them to seconds, and letting wired keyframes place themselves in the sentence.
- 4 min read
How to sync AI music to your video, in both directions
Cutting picture to a track and writing a track to a cut are the same problem read from opposite ends. Both come down to one thing: a timing that means the same instant to every tool that reads it.
- 4 min read
Image to video with AI: first frames, reference images, and the difference
An image handed to a video model can be two completely different instructions — the frame it starts on, or the look it borrows. Here is how to tell them apart, why the order you send them in matters, and how to wire a still into a clip.
Build the graph these posts are about.
QueyFrames is in early access. Create an account to join the list.