Scene format
The JSON scene the engine draws, with its fields, keyframes, layers and layout.
A scene is one JSON file. The same scene and frame give the same pixels every time.
A project file (TSX) makes a scene for each frame. You can also write a scene by hand. Every command takes a .json file as its entry. render draws a scene in one pass, not in worker threads.
This scene moves and turns a card:
{
"width": 640,
"height": 360,
"fps": 30,
"durationInFrames": 60,
"background": "#14171f",
"layers": [
{
"id": "card",
"type": "shape",
"shape": { "kind": "roundedRect", "width": 360, "height": 200, "radius": 28 },
"fill": "#f6c177",
"stroke": { "color": "#ffffff", "width": 4 },
"transform": {
"x": [
{ "frame": 0, "value": 200, "easing": "easeOut" },
{ "frame": 30, "value": 140 }
],
"y": 80,
"rotation": [
{ "frame": 0, "value": -8, "easing": "easeInOut" },
{ "frame": 59, "value": 8 }
]
}
}
]
}Render a frame of it with npx kinetograph still scene.json 15. The PNG goes to out/stills/.
Top-level fields
| Field | Type | Notes |
|---|---|---|
width, height | integer | Pixels, from 1 to 8192. |
fps | number | Above 0. The frame rate used when encoding. |
durationInFrames | integer | At least 1. Valid frames run from 0 to durationInFrames minus 1. |
background | colour | Optional. The default is #000000. It may be transparent. |
margin | integer | Optional. The least canvas margin in pixels. |
fonts | object | Font family names to font file paths. A text layer names one of these families. |
camera | object | The viewpoint for 3D transforms. |
layers | array | Bottom layer first. The last layer is on top. |
Paths in the scene are relative to the scene file. Only the fonts listed in fonts exist. There is no fallback to a system font.
Animated numbers
Any number in a scene can be a constant or a list of keyframes.
For example, "x": 100 is a constant, and "x": [{"frame": 0, "value": 0, "easing": "easeOut"}, {"frame": 30, "value": 640}] moves from 0 to 640.
- Keyframes go in increasing
frameorder. Two keyframes on the same frame make a step. - Before the first keyframe, the first value holds. After the last, the last value holds.
easingshapes the segment that starts at that keyframe. It islinear(the default),easeIn,easeOutoreaseInOut.
Colours, strings and paths are not animated. Colours are #rgb, #rrggbb, #rgba, #rrggbbaa or transparent.
Layers
Every layer has these fields:
| Field | Default | Notes |
|---|---|---|
id | required | Unique in the whole scene, including nested layers. |
type | required | shape, text, image, group, noise, meshGradient, lottie, canvas, scene3d, video or gif. |
transform | identity | Position, scale, rotation and anchor. |
opacity | 1 | Clamped to 0 to 1. |
blendMode | normal | One of the 16 modes of W3C Compositing and Blending Level 1, such as multiply or screen. |
effects | [] | Applied in order before the layer is blended. |
clip | none | Cuts the layer to a shape. |
mask | none | Fades the layer with a gradient. |
matte | none | Cuts the layer with a sibling layer. |
motionBlur | none | Averages the layer over the shutter time. |
layoutItem | none | How the layer takes part in its parent's flexbox layout. |
The transform fields are x, y, scale, scaleX, scaleY, rotation (degrees, clockwise), anchorX, anchorY, rotateX, rotateY, z, originX and originY. Each is an animated number. The defaults are 0, except scale, scaleX and scaleY, which are 1. scaleX and scaleY stretch one axis and multiply with scale.
Layer types
A shape has a shape object, a fill and an optional stroke. shape.kind is rect, roundedRect, ellipse or path. A path takes d, SVG path data in layer coordinates.
A stroke can also take cap (butt, round or square), join (miter, round or bevel), miterLimit, dashArray (dash and gap lengths, alternating) and dashOffset, as SVG's can.
A text layer names a font from fonts:
{ "id": "title", "type": "text", "text": "Hello\nworld", "font": "DM Sans",
"size": 64, "color": "#ffffff", "lineHeight": 1.2, "maxWidth": 600 }\nstarts a new line, andmaxWidthsets the wrap width.alignisleft,centerorright.- There is one font per layer and no bidi.
- A character the font lacks falls back to the symbol fonts that ship with Kinetograph: arrows, check marks, maths signs and monochrome emoji. A character none has is drawn as a box, and
inspectlists it asmissingChars.
An image layer draws a PNG or JPEG file from src, with width and height. fit is fill (the default), contain or cover, as in CSS object-fit.
A group holds children. It composites them into its own buffer, then blends the result with its opacity and blend mode.
The other types (noise, meshGradient, lottie, canvas, scene3d, video, gif) have their own fields. See SCENE.md.
Gradients
A shape's fill and a text layer's color take a gradient in place of a colour. type is linear, radial or conic. A gradient needs at least two stops, each with an offset and a color. The coordinates (x0, y0, x1, y1 for linear) are in the layer's own space. Add "extend": "repeat" or "reflect" to repeat it.
Layout
A group with a layout places its children with flexbox. Any layer can take part with layoutItem:
{ "id": "row", "type": "group",
"layout": { "flexDirection": "row", "gap": 24, "width": 1080, "height": 400 },
"children": [
{ "id": "b", "type": "text", "text": "hi", "font": "DM Sans", "size": 64, "color": "#fff",
"layoutItem": { "flexGrow": 1, "margin": 8 } } ] }Layout is flexbox only, with sizes in pixels. Names and values follow CSS. The full list of fields is in SCENE.md.
Effects and unknown fields
Effects go in a layer's effects list. Each entry has a type, such as blur, glow, dropShadow, grain or displace. npx kinetograph effects lists them with their fields.
The loader ignores fields it does not know, so a misspelt optional field has no effect and shows no error. Check a scene with inspect and lint.
SCENE.md has every field, layer type and effect, including the canvas margin and the 3D camera. The Authoring guide covers the TSX side that writes these scenes.