AI JSON: Smart Lines, Smart Arrows & Connectors
Use native smartLine and smartArrow objects when AI-generated template JSON needs an editable relationship, route, or directional connection. A native connector can follow attached objects after import; an SVG imitation cannot provide that semantic relationship.
This page describes portable TemplateEnvelopeV1 JSON for File → Import AI JSON. It does not describe the internal object representation stored in a .scribe package.
The three connector data layers
| Field | Role | What may change during drawIn |
|---|---|---|
props.smartLine | Semantic Smart Stroke route: start, end, route mode, controls, elbow data, route points, and arrow heads | Nothing; its world attachment geometry stays stable |
top-level connector | Optional start/end attachments to other object IDs and their anchors | Only the resolved endpoint may change when an attached target genuinely moves, rotates, or changes bounds |
props.paths | Drawable path data consumed by the renderer | Visible stroke progress may change |
animationType: "drawIn" is a reveal. It changes how much of props.paths is visible. It must not scale, translate, rotate, or otherwise move the semantic endpoints in props.smartLine.
Supported endpoint anchors
Each attached endpoint uses one of these anchors:
autochooses a side from the other endpoint or target at evaluation time;topuses the center of the target's top edge;rightuses the center of the target's right edge;bottomuses the center of the target's bottom edge;leftuses the center of the target's left edge; andcenteruses the target's center.
Named anchors rotate with their target. auto is useful when layout may change; named anchors are better when the relationship must remain on a particular side.
Standalone Smart Line
Add this portable ObjectDTO to a scene or block objects array:
{
"id": "standalone-line",
"type": "smartLine",
"x": 180,
"y": 220,
"width": 360,
"height": 1,
"props": {
"smartLine": {
"routeMode": "straight",
"start": { "x": 0, "y": 0 },
"end": { "x": 360, "y": 0 }
},
"paths": [
{
"id": "standalone-line-path",
"d": "M0 0 L360 0",
"stroke": "#1F2937",
"strokeWidth": 4,
"fill": "none"
}
],
"strokeColor": "#1F2937",
"strokeWidth": 4
}
}
Without top-level connector metadata, both endpoints remain standalone and editable.
Standalone Smart Arrow
Use smartArrow and an endHead when the relationship has direction:
{
"id": "standalone-arrow",
"type": "smartArrow",
"x": 180,
"y": 320,
"width": 360,
"height": 1,
"props": {
"smartLine": {
"routeMode": "straight",
"start": { "x": 0, "y": 0 },
"end": { "x": 360, "y": 0 },
"endHead": { "type": "arrow" }
},
"paths": [
{
"id": "standalone-arrow-path",
"d": "M0 0 L360 0",
"stroke": "#111111",
"strokeWidth": 4,
"fill": "none"
}
],
"strokeColor": "#111111",
"strokeWidth": 4
}
}
The semantic endHead makes this a native arrow. Do not replace it with a manually drawn SVG triangle when the arrow must remain editable.
Attached Smart Arrow
The maintained canonical example contains two rectangles and one attached native Smart Arrow with explicit right → left anchors:
Download the tested TemplateEnvelopeV1 fixture
Its attachment and semantic geometry are:
{
"id": "arrow-a-b",
"type": "smartArrow",
"x": 300,
"y": 330,
"width": 480,
"height": 1,
"connector": {
"start": { "targetObjectId": "box-a", "anchor": "right" },
"end": { "targetObjectId": "box-b", "anchor": "left" }
},
"props": {
"smartLine": {
"routeMode": "straight",
"start": { "x": 0, "y": 0 },
"end": { "x": 480, "y": 0 },
"endHead": { "type": "arrow" }
},
"paths": [
{
"id": "arrow-a-b-path",
"d": "M0 0 L480 0",
"stroke": "#111111",
"strokeWidth": 4,
"fill": "none"
}
],
"strokeColor": "#111111",
"strokeWidth": 4
},
"animationStart": 700,
"animationDuration": 900,
"animationType": "drawIn"
}
box-a and box-b must exist in the same template object scope. Template application remaps all three object IDs together, including both targetObjectId references.
The tested fixture has no external assets, uses deterministic template-local IDs, and keeps all animation timing inside its 5000 ms scene.
Add or remove Draw In
Template v1 object animation timing uses milliseconds:
{
"animationStart": 700,
"animationDuration": 900,
"animationType": "drawIn",
"animationEasing": "linear"
}
These fields are optional. Remove them when the complete connector should be visible immediately. Adding them changes visible draw progress only. If attached targets are stationary, the connector's semantic world start and end points remain equal at the start, middle, and end of the reveal.
Do not paste a .scribe runtime object
Portable Template JSON and .scribe runtime objects are related, but they are different formats.
This is a runtime-shaped object and is not portable AI Template JSON:
{
"type": "smartArrow",
"properties": {
"smartLine": {}
}
}
The portable form uses props:
{
"id": "portable-arrow",
"type": "smartArrow",
"x": 0,
"y": 0,
"props": {
"smartLine": {
"routeMode": "straight",
"start": { "x": 0, "y": 0 },
"end": { "x": 240, "y": 0 },
"endHead": { "type": "arrow" }
},
"paths": [
{ "id": "portable-arrow-path", "d": "M0 0 L240 0", "stroke": "#111111", "strokeWidth": 4, "fill": "none" }
]
}
}
The importer reports an actionable error when a smartLine or smartArrow uses runtime properties without portable props. It does not silently reinterpret arbitrary .scribe runtime state.
Verification checklist
After import:
- confirm the object remains a native Smart Line or Smart Arrow;
- inspect both endpoint attachments and anchors;
- scrub before, through, and after any
drawIninterval; - verify stationary targets do not produce endpoint drift;
- move and rotate each target to confirm the connector follows real changes; and
- save or export only after the final frame and backward/forward scrubbing remain stable.
See Create and import AI JSON, the template schema reference, and Smart Lines and Arrows for the surrounding workflows.