Skip to main content
A shape asset draws a rect, ellipse, circle, triangle, diamond, or any SVG path you paste in. No image to make, no file to host, and it stays sharp at any output resolution.
That is a bar across the lower third, dark enough to read a title on and thin enough to see the footage through. Put it on a track below the text. A shape is placed the way every clip is placed: by the clip’s transform. size is its box, position its centre unless anchor says otherwise, and rotate turns it about that anchor. The asset itself only says what to draw. With no size a shape fills the frame, which is a scrim or a background in one line. Like text it has no duration of its own, so leaving length off runs it to the end of its container. width is a percent of the frame’s width and height a percent of its height. Both also take pixels as plain numbers.

a bar and a text track

before

width keyframed 2% to 86%

rect, ellipse, circle, triangle, diamond

Fills and edges

before

two colours, diagonal

before

stroke with no fill

before

radius 0.4

before

softness 0.3

before

a shadow behind it

Paths

before

SVG path data

Leave the height out to get a circle

Omit size.height and the box is made square in pixels. That is the only way to get a true circle or square on a frame that is not square, and it is the one thing about shapes worth memorising. A 10% by 10% box on a 16:9 frame is 192 by 108 pixels. Rounding it fully gives a pill, not a circle. Omit the height and the engine derives 17.8% for you.
shape: "circle" is ellipse with that rule applied, so it rejects an explicit height rather than quietly ignoring one. The same omission works on every kind: a rect with no height is a square, a diamond with no height is a regular one.

Anchor

anchor: "topLeft" points position at the box’s corner instead of its centre. It is what makes letterbox bars arithmetic-free.

Fills, flat and gradient

color takes #RRGGBB, or the 8-digit #RRGGBBAA for a constant translucency the way #0A0A0ACC does above. Do not reach for the clip’s opacity instead. opacity fades the whole clip, so keep it for fades and put a constant translucency in the colour. Give color two colours and it is a gradient. gradient names the direction: vertical (the default), horizontal, diagonal or radial.
The gradient maps to the shape, not the frame, so a small badge shows the whole ramp instead of a sliver of one. Stops take the 8-digit form too, which is how you get a scrim that fades to nothing: ["#0A0A0A00", "#0A0A0AFF"].

Outlines, with a real hole

stroke draws a border just inside the shape’s edge, its width in pixels of the output frame. Give the shape a color too and you get a filled shape with a border; radius rounds both together. Leave color out and only the outline draws. What it surrounds is genuinely transparent, not filled with black, so the footage shows through the middle. That works on every kind except a path.

Rounded corners

radius runs from 0 (square) to 1 (fully round) on a rect. At 1 a wide box becomes a pill and a square one becomes a circle.

Drop shadows

shadow follows the shape, including its outline, its rotation and its animation. Every field has a default, so "shadow": {} is a sensible shadow.

Rotation turns about the anchor, not the frame

transform.rotate is degrees clockwise about the shape’s own anchor, so it spins where it sits rather than orbiting the middle of the frame. A diagonal rule is a thin rect and one field:
There is no line type for the same reason there is no square type: a line is a rect with a small height, and rotate is what makes it diagonal.

Softness

softness runs 0 to 1 and feathers the edge. At 0.2 to 0.4 an ellipse reads as a spotlight or a vignette rather than a hard-edged disc. A full-frame ellipse with softness: 0.5 and a radial ["#00000000", "#000000CC"] fill is a vignette with no image asset at all.

Paths

shape: "path" takes SVG path data straight out of a design tool. viewBox gives the coordinate space it was drawn in, defaulting to "0 0 100 100", and the path is scaled into the transform’s size so the same data works at any size on any frame.
M L H V C S Q T Z are supported, absolute and relative. Elliptical arcs (A) are refused rather than approximated, so re-export with arcs converted to curves. A path takes a fill, a gradient, a shadow, rotation and softness, but not a stroke: outlining arbitrary path data needs true path offsetting.

Animation

Everything that moves is keyframes: position, size and rotate on the transform, color and radius on the shape. A progress bar is a width that grows.
A shape that is square in pixels stays square as it grows, so an animated circle does not turn into an ellipse halfway through. A solid colour can animate into a gradient, and a square can round itself off with keyframes on radius. An animated rotate has no limit: 0 to 720 is two full turns.

Combinations the API refuses

Two engine primitives draw shapes and they have different abilities, so a few combinations are rejected at submit time rather than rendered wrong. Each error names the fix.

What else a shape takes

blendMode mixes it with the layer below, effects apply to it like any clip, and opacity keyframes fade it in and out. A track holding only shapes composites as a base layer, so a solid colour background is a timeline that references no files at all. There is no arbitrary path stroke and no per-corner radius. Anything past that is still an image asset. Every shape field is in the shape reference.
Last modified on September 24, 2026