All docs

JSON format

The openCanviz JSON format

What an openCanviz JSON file contains, how to import one, and how scenes, nodes, edges and steps fit together.

Last updated

Every openCanviz project can be written as one JSON file. You can write that file yourself, or ask an AI chatbot to write it, then paste it into Import on the Create page to get a project you can play, edit and download. The schema reference lists every field, JSON examples has complete files to copy, and JSON rules for AI agents has a checklist and a prompt.

Where JSON comes in

Import does not check every field. It needs valid JSON with either a diagrams list or a nodes list. A file that imports but breaks the rules on these pages can still play wrongly, so validate it against the schema file first.

The top-level shape

A project file is one object:

  • $schema: optional, https://opencanviz.com/schema/v1.json. Code editors such as VS Code use it to check the file and suggest fields as you type. Import ignores it.
  • title: the project name.
  • artboard: the video frame, its position, size and background color.
  • diagrams: the scenes, in playback order. Each scene has nodes, edges, steps and optional narration.
  • Optional project settings such as sceneNames, transitions between scenes, showCaptions and captionStyle.

A single-scene file may put nodes, edges, steps and narration at the top level instead of inside diagrams.

A minimal example

Two boxes and an arrow. In step 0 "Idea" fades in; in step 1 the arrow draws itself and "Video" fades in.

{
  "$schema": "https://opencanviz.com/schema/v1.json",
  "title": "Idea to video",
  "artboard": { "x": -960, "y": -540, "width": 1920, "height": 1080, "background": "#0f172a" },
  "diagrams": [
    {
      "nodes": [
        { "id": "a", "kind": "rect", "x": -500, "y": -90, "w": 320, "h": 180, "cornerRadius": 16, "fill": "#1e293b", "stroke": "#38bdf8", "strokeWidth": 3, "label": "Idea", "labelColor": "#f8fafc", "labelFontSize": 40 },
        { "id": "b", "kind": "rect", "x": 180, "y": -90, "w": 320, "h": 180, "cornerRadius": 16, "fill": "#1e293b", "stroke": "#a78bfa", "strokeWidth": 3, "label": "Video", "labelColor": "#f8fafc", "labelFontSize": 40, "opacity": 0 }
      ],
      "edges": [
        { "id": "a_to_b", "from": "a", "to": "b", "stroke": "#94a3b8", "width": 4, "arrow": "end", "trim": 0 }
      ],
      "steps": [
        {
          "id": "intro",
          "durationMs": 1500,
          "caption": "Every video starts with an idea.",
          "nodes": [
            { "id": "a", "kind": "rect", "x": -500, "y": -90, "w": 320, "h": 180, "cornerRadius": 16, "fill": "#1e293b", "stroke": "#38bdf8", "strokeWidth": 3, "label": "Idea", "labelColor": "#f8fafc", "labelFontSize": 40 },
            { "id": "b", "kind": "rect", "x": 180, "y": -90, "w": 320, "h": 180, "cornerRadius": 16, "fill": "#1e293b", "stroke": "#a78bfa", "strokeWidth": 3, "label": "Video", "labelColor": "#f8fafc", "labelFontSize": 40, "opacity": 0 }
          ],
          "edges": [
            { "id": "a_to_b", "from": "a", "to": "b", "stroke": "#94a3b8", "width": 4, "arrow": "end", "trim": 0 }
          ],
          "actions": [
            { "type": "visibility", "target": { "kind": "node", "id": "a" }, "mode": "fadeIn", "durationMs": 500 }
          ]
        },
        {
          "id": "result",
          "delta": true,
          "durationMs": 2000,
          "caption": "openCanviz turns it into a video.",
          "nodes": [{ "id": "b", "opacity": 1 }],
          "edges": [{ "id": "a_to_b", "trim": 1 }],
          "actions": [
            { "type": "edgeTween", "target": { "kind": "edge", "id": "a_to_b" }, "from": { "trim": 0 }, "to": { "trim": 1 }, "durationMs": 700, "ease": "ease-out" },
            { "type": "visibility", "target": { "kind": "node", "id": "b" }, "mode": "fadeIn", "durationMs": 400, "offsetMs": 700 }
          ]
        }
      ]
    }
  ]
}

Coordinates and units

  • Positions and sizes are in pixels. x and y are a node's top-left corner, and w and h are its width and height.
  • The artboard is the part of the canvas that becomes the video. A 1920 by 1080 frame centered on the origin has x -960 and y -540. Use 1080 by 1920 for a vertical Short and 1080 by 1080 for a square.
  • Times are in milliseconds, and opacity and progress values run from 0 to 1.
  • Colors are hex strings such as #38bdf8.

Ids

Every node and edge has an id that is unique within its scene and stays the same in every step. Steps refer to nodes and edges only by id. Edges connect two nodes with from and to, which must be ids of nodes in the same scene. Giving each scene its own id prefix, such as s1_ and s2_, keeps ids unique across the project.

How steps and timing work

A scene plays its steps in order. Each step lasts durationMs milliseconds, and the scene lasts the sum of its steps. Scenes play back to back.

  • Step 0 is a full snapshot. It lists every node and edge as it looks at the start, including ones that appear later, which start at opacity 0. The scene's own nodes and edges lists match step 0.
  • Later steps list changes. Mark them "delta": true and list only the properties that change, by id. Add new nodes with addNodes and remove nodes with removeNodeIds.
  • Changes animate on their own. When a position, size, color or opacity differs from the step before, openCanviz tweens it across the step.
  • Actions control the details. A step's actions add effects such as a fade, a slide or an arrow drawing in, each with its own offsetMs and durationMs inside the step.
  • Captions and narration. A step's caption is the line shown on screen. Narration lines you include import as text only. Open the Narration panel and click Generate All Scenes to give them a voice, and the steps then stretch to fit the audio. See Narration and voice.

All Rights Reserved.