Motion, keyframes and transitions
Animate editable properties with fractional keyframes and connect scenes with the transition catalog.
Keyframes animate one layer while it exists. Transitions connect an outgoing clip to an incoming clip. Entrance and exit presets in Studio write ordinary keyframe tracks, so their result stays editable through API and MCP.
API request journey
Position, scale, opacity and blur tracks move through a multi-scene technical story.
Property tracks
data-jc-animation contains JSON encoded for an HTML attribute:
{
"transformOrigin": "center center",
"tracks": [
{
"id": "card-position",
"property": "position",
"keyframes": [
{ "id": "p0", "time": 0, "value": { "x": -80, "y": 0 }, "easing": "ease-out" },
{ "id": "p1", "time": 0.7, "value": { "x": 0, "y": 0 }, "easing": "ease-in-out" }
]
},
{
"id": "card-opacity",
"property": "opacity",
"keyframes": [
{ "id": "o0", "time": 0, "value": 0, "easing": "linear" },
{ "id": "o1", "time": 0.45, "value": 1, "easing": "ease-out" }
]
}
]
}Times are fractional seconds relative to the owning layer. Supported properties include position, scale, 2D/3D rotation, opacity, size, blur, color, background, clip path and audio volume.
MCP/Agent patch_clip replaces each submitted property track in full while preserving other property tracks. For example, adding rotation does not discard position. Use animation: null to clear all tracks; keyframe arrays are not partial append operations. An authoring call accepts at most 24 actions, separately from the limit of 256 keys per submitted track.
Named curves are linear, ease-in, ease-out, ease-in-out and back-out.
Custom cubic-bezier(x1,y1,x2,y2) curves are accepted throughout authoring and rendering: X controls must be between 0 and 1; all controls must be finite. The easing on the destination key controls the incoming segment. For example, use cubic-bezier(0.22,1,0.36,1) for a fast arrival with a soft finish.
Motion programs: one timeline, independent properties
For composed motion, use the Motion program section in Studio or
patch_clip with animation.program. It uses the same preview and export
contract. Discover the complete schema through get_primitive_catalog with
kind: "motion" (Studio Agent: list_motion_presets). No separate chart engine
or runtime package is needed.
| Control | What it does |
|---|---|
x, y, width, height | Animate pixel geometry |
scale, rotation, opacity | Scale multiplier, additive degrees, absolute opacity |
drawStart, drawEnd | Independently trim a native vector stroke from 0 to 1 |
pathProgress + follow | Move a separate layer along the actual curve, independently of its reveal |
number | Animate native text with decimals, prefix and suffix |
input | Animate a declared numeric custom-block input, read inside jsoncut.onFrame |
Each segment has an ID, property, from, to, start at and duration.
Times are local seconds. at can instead be { "cue": "arrival", "offset": 0.15 }
with cues: { "arrival": 1 }; reuse cue names and increment offsets to stagger
related layers. Cues are stored per layer, not as global project variables.
repeat counts extra iterations; gap holds the endpoint between them;
yoyo reverses alternate iterations. Final values hold. No fade-out is inserted.
Choose easing or spring: { mass, stiffness, damping, velocity } on each
segment. Springs work on any numeric channel and are normalized to finish at
the requested endpoint over that duration. This is a timed spring response,
not a collision/rigid-body simulation. Progress and opacity remain clamped to
0–1; geometry dimensions remain positive.
This patch makes an existing layer follow a previously created native path:
{
"animation": {
"tracks": [],
"program": {
"version": 1,
"segments": [{
"id": "signal", "property": "pathProgress",
"from": 0, "to": 1, "at": 0.5, "duration": 1,
"repeat": 2, "gap": 0.2, "easing": "linear"
}],
"follow": {
"pathId": "your-existing-path-id",
"anchorX": 0.5, "anchorY": 0.5,
"orient": true, "rotationOffset": 0
}
}
}
}The layer must last at least 3.9 seconds. Create targets first and use their real IDs. Imported SVG image contents are not native paths.
To connect nodes, put connector on a native vector layer:
{
"from": { "clipId": "source-node", "x": 1, "y": 0.5 },
"to": { "clipId": "destination-node", "x": 0, "y": 0.5 },
"bend": 0.55
}Anchor coordinates are fractions of the target layer's bounds. Moving or
resizing either node updates the connection. bend: 0 gives a straight line;
larger values produce horizontal-tangent curves. Edit a native vector directly
for other curve shapes. Followers work on either kind of path.
Ownership and editing
- One owner per property: do not combine a program channel with the same property track or measured audio binding. Clear conflicts explicitly.
- Spatial bindings support 2D layer and parent transforms. Cycles, missing targets and 3D bindings are rejected; invisible references hide their dependents.
- Programs cannot share a layer with legacy
proceduralormotiondescriptors. Existing projects keep their old behavior without migration. animation.program: nullremoves only the program;animation: nullremoves the complete animation. Submitted programs replace the whole program; omitted programs and unrelated property tracks are retained by Agent/MCP patches.- At most 64 segments, 32 cues and 1000 extra iterations. Segments on the same channel may be sequential, not overlapping; all timing must fit the layer.
- Group duplication remaps internal references. Delete a complete group or detach external bindings before deleting their targets. Splitting program layers is explicitly blocked; duplicate and retime them instead. Ungrouping a group with its own program is also blocked until that program is removed; this prevents silently discarding group motion. Cross-project paste must include referenced targets, not just the follower.
Native starting compositions
Search the shared Library for component.native-flow, component.native-chart,
component.native-logo or component.native-process. Every node, line, moving
signal, column, value and label is an ordinary editable layer. These are starting
compositions, not a hidden data engine: edit their layers and motion segments to
change the design. Existing hybrid recipes remain available when an intentionally
code-controlled inner graphic is preferable.
Native connected flow
Six independently timed signals follow anchor-connected curves. Nodes, labels, paths and signals remain separate Studio layers. Exported at 60 source fps.
Legacy parametric motion
For a physical spring, apply Library item motion.physical-spring to a selected visual layer. The Parametric motion inspector exposes mass, stiffness, damping, initial velocity, distance and seconds. Its horizontal offset adds to existing keyframes. The analytic spring is evaluated from local layer time on every seek; it does not depend on playback history or create hundreds of keys. Durations from 0.05 to 3600 seconds are supported.
The same inspector also supports Number counter on text and Draw path + follower on vector paths. Counter typography remains native and editable; its from, to, prefix, suffix, precision and easing control the displayed number. A path's reveal and oriented marker use its actual curve, including resized anchors. Use Library items motion.native-counter and motion.native-path, or a validated procedural layer patch, from MCP. These are native controls, distinct from the optional code-edited hybrid artwork recipes.
Only one parametric motion system is active per layer. Use separate layers for independent effects. Image compositions do not support animation. Public rendering still samples source frames; experimental temporal-sampling research is not a public render option.
For example, patch an existing text layer with this descriptor. Use the normal authoring endpoint/tool and its current project version; position, typography and other motion tracks remain unchanged.
{
"procedural": {
"type": "counter",
"from": 0,
"to": 2400,
"decimals": 0,
"prefix": "",
"suffix": "+",
"seconds": 2,
"easing": "cubic-bezier(0.22,0,0.36,1)"
}
}Set procedural to null to remove the system. A counter replaces the visible text while active, so do not combine it with a character-based entrance on the same layer.
Source and output FPS
For smooth 60 fps animation, set the project to 60 fps before authoring and export at 60 fps. Exporting a 30 fps source at 60 fps does not create new motion states; preflight warns about that upconversion. Temporal motion blur is not currently a public output option.
Scene transition
<section id="scene-result" data-jc-clip data-jc-kind="scene"
data-jc-start="4.1" data-jc-duration="4.5" data-jc-track="0"
data-jc-transition="mask-bars-vertical"
data-jc-transition-duration="0.62"
data-jc-transition-easing="ease-in-out"
data-jc-transition-from="scene-request"
data-jc-transition-to="scene-result">
</section>Use keyframes to move an object from A to B. Use a transition when the edit itself changes from one scene or clip to another.
Animatable properties
| Family | Properties |
|---|---|
| Transform | position, scale, rotation, rotationX, rotationY |
| Visibility and geometry | opacity, width, height, clipPath |
| Image treatment | blur, brightness, saturation, hue |
| Design | color, background |
| Audio | volume |
Position values use {x,y} with optional z. Color, background and clip path use strings. Other tracks use finite numbers. A layer may have only one track per property, and every keyframe time must fall between zero and that layer's duration.
Easing
Built-in values are linear, ease-in, ease-out, ease-in-out and back-out. A CSS-compatible cubic-bezier(x1,y1,x2,y2) is also accepted when both X control points stay between zero and one.
The easing on a keyframe controls interpolation from the previous keyframe into that keyframe.
Presets remain editable
Studio entrance and exit presets generate ordinary property tracks. Families include fades, slides, wipes, geometric reveals, slices, dynamics, depth and focus effects. After applying a preset, inspect and adjust its tracks like any other motion.
Text layers additionally support independent entrance and exit effects with all, word, character or line staggering. Replacement and shimmer effects have bounded text-specific controls; they do not introduce executable code.
New text layers start with no entrance or exit effect. In Studio, choose None / Off above either text-effect library to disable that phase. Text exit was previously labelled “Keep visible”. An entrance does not automatically add an exit. Animated library presets can deliberately include effects.
For apply_text_motion, use effect: "none" and exitEffect: "none" to disable both text phases. Omitting exitEffect preserves an existing exit. These controls do not remove separate layer or parent keyframes, transitions, or the clip's end time; inspect those if the layer still disappears.
Transition constraints
The transition is stored on the destination clip. Its duration must be positive and fit inside that destination. When fromClipId is supplied, the source must exist and be adjacent to or overlap the destination at the edit point. Keep toClipId equal to the owning destination ID.
Transition families
The public catalog includes dissolves and color dips; directional pushes, slides and wipes; diagonal, circle and iris reveals; blur, zoom and exposure changes; light leak, film burn and flash effects; glitch, RGB split and pixelation; bar, blind and checker masks; 3D flips, cubes and page turns; plus luma, ripple, warp, split and shutter transitions. Use the live Studio catalog for visual selection and the source schema for the stable transition ID.