Custom DOM, Canvas and WebGL blocks
Add expert visuals without turning the complete project into opaque JavaScript.
Use a custom block for a procedural background, data visualization or 3D visual that ordinary layers cannot express. Its geometry, timing, opacity and transitions still live on a normal custom layer, so Studio can position and animate the result.
Generative border study
A procedural visual remains one bounded layer inside an otherwise ordinary editable project.
Layer and block
<div id="network-field" data-jc-clip data-jc-kind="custom"
data-jc-name="Network field" data-jc-start="0" data-jc-duration="10"
data-jc-track="1"
style="left:0;top:0;width:1920px;height:1080px"></div>{
"customBlocks": [
{
"layerId": "network-field",
"adapter": "canvas-2d",
"html": "<canvas></canvas>",
"css": "canvas{display:block;width:100%;height:100%}",
"javascript": "const canvas=document.querySelector('canvas'); const context=canvas.getContext('2d'); const {width,height}=jsoncut; canvas.width=width; canvas.height=height; jsoncut.onFrame((milliseconds)=>{ const time=milliseconds/1000; context.clearRect(0,0,width,height); context.fillStyle=jsoncut.inputs.color; context.beginPath(); context.arc(width/2+Math.sin(time)*180,height/2,120,0,Math.PI*2); context.fill(); });",
"inputs": { "color": "#ff9418" }
}
]
}Adapters are dom, svg, canvas-2d and webgl. The block receives project-controlled time, dimensions and declared inputs. Network access, storage, workers, navigation and parent-document access are blocked.
javascript runs once to initialize the block. Register jsoncut.onFrame(callback)
to draw directly at each requested time: its argument is clip-local milliseconds.
jsoncut.time is clip-local seconds, jsoncut.frame is the local frame index at
jsoncut.fps (the project frame rate). Calculate the complete visual state from time
so scrubbing backwards produces the same result. Do not accumulate counters per callback.
The legacy source field instead runs a frame function with an api object. That
object is not available in javascript; do not mix the two modes. A custom block
stays one selectable layer: its internal drawing is not automatically split into
editable Studio text or shape layers. Keep primary text in ordinary text layers.
Keep ordinary concerns outside the code:
- use layer CSS for position and size;
- use
data-jc-animationfor editable motion; - use normal transitions for clip changes;
- expose user-editable settings as block
inputs; - prefer ordinary text, media, vector and group layers whenever possible.
Ready-made parametric graphics
Studio's shared Library and MCP expose the same recipes. Search for animated counter, draw a path or build the graph, then inspect the exact properties before inserting:
| Library ID | Editable controls | Layer model |
|---|---|---|
component.animated-counter | Start/end number, decimals, suffix, color and seconds | Native title + Canvas number |
component.path-draw-follower | Bend, stroke, marker, color and seconds | Native title + Canvas path/follower |
component.staggered-graph | Node count, color and seconds | Native title + Canvas graph |
Select the graphic layer in Studio to adjust its custom inputs. The inner drawing is not a set of native shape layers. Repeated forward/backward seeks derive the same state directly from clip-local time.