Masks
Cut what a clip shows with rectangles, ellipses, bezier and free-hand shapes: feathered, expanded, inverted, combined and keyframed, from the monitor or from an agent with setMask.
A clip's masks cut what it shows: only the parts the masks keep reach the frame, so a clip can be isolated, revealed or cut through, and anything under it shows in the gaps. They live in props.masks on any video, image, svg, text or adjustment clip. On an adjustment layer they limit where its effects and grade apply. They run in preview and export alike. The clip draws as usual, the masks cut it, and then its opacity and blend composite it.
"masks": [
{ "name": "Subject", "shape": "ellipse", "x": 0.52, "y": 0.45, "w": 0.4, "h": 0.7, "feather": 40 },
{ "name": "Hole", "shape": "rect", "mode": "subtract", "x": 0.6, "y": 0.4, "w": 0.1, "h": 0.1 },
{ "shape": "bezier", "x": 0.3, "y": 0.7, "expand": 8,
"points": [[0, -0.1], [0.12, 0.08, 0, -0.05, 0, 0.05], [-0.12, 0.08]],
"keys": [{ "t": 0, "x": 0.3 }, { "t": 2, "x": 0.6, "ease": "linear" }] }
]| key | default | does |
|---|---|---|
shape | - | rect · ellipse · bezier (write freehand with a stroke to have one drawn for you) |
x · y | 0.5 | centre, as fractions of the clip's picture (0…1, y down) |
w · h | 0.5 | size, fractions of the picture's width / height (rect, ellipse) |
points | - | bezier: 3–64 anchors around x, y, each [dx, dy] (a corner) or [dx, dy, inX, inY, outX, outY] (with curve handles relative to the anchor), all fractions of the picture's width / height |
stroke | - | freehand only: [[u, v], …] picture fractions along an outline; it is simplified and stored as an editable bezier |
scale · rotation | 1 · 0 | about the centre; degrees clockwise |
mode | add | how this mask combines with the ones before it: add · subtract · intersect · difference |
invert | false | use everything outside the shape |
opacity | 1 | 0…1, how strongly this mask counts |
feather | 0 | soft edge, project pixels, centred on the outline |
expand | 0 | grow (+) or shrink (−) the outline, project pixels |
name · on | - | a label; on:false turns the mask off |
keys | - | animate it: [{t, x?, y?, w?, h?, scale?, rotation?, feather?, expand?, opacity?, points?, ease?}], t in seconds from the clip's start; each param eases between the keys that set it (ease on the arriving key, as for clip keyframes). points keys morph the outline and need the shape's point count |
Masks combine bottom-up (first in the list first). The first one starts from nothing when it adds and from the whole picture otherwise, so a lone subtract cuts a hole in a full picture. At most 8 masks per clip.
The picture a mask lives in is the clip's drawn rectangle for video, image and svg (after fit and crop), the text block for text, and the whole canvas for an adjustment layer. Masks follow the clip when it is moved, scaled, rotated or flipped, and keep the clip's keyframes.
In the editor, the Masks section of the Inspector has + Rect, + Ellipse, Pen (click points on the monitor, drag while placing one to pull curve handles, click the first point or press Enter to close) and Draw (drag a free-hand outline). Matte shows the clip's matte in the monitor (white = visible). Pick a mask's chip to edit it: mode, Invert, the sliders, ↑ ↓ to reorder, Copy, Delete, and on the monitor, drag inside to move it, the edge handles to resize it and the knob to rotate it (Shift snaps to 15°). On a bezier, drag a point to move it, drag its handles to curve it (Alt breaks the pair), Alt-drag a point to pull fresh handles, Ctrl-click the outline to add a point, and double-click a point to remove it. ◆ Key keys the whole mask at the playhead; once it has keys, every change keys. Esc steps back (point, then mask).
Agents edit masks with patch ops:
{op:"setMask", id, set:{shape:"ellipse", x:0.5, y:0.45, w:0.4, h:0.7, feather:40}}adds a mask (nomask, an index one past the end or a new name adds one; a new mask needsshape).{op:"setMask", id, mask:"Subject", set:{x:0.6}}edits one, by index (0 = first) or name, merging key by key (nullresets a key).replace:truestarts it over, keeping its name.ids:[…]edits several clips.- A drawn outline:
set:{shape:"freehand", stroke:[[0.4, 0.3], [0.6, 0.32], …]}. It is stored as an editable bezier. {op:"setMaskKeys", id, mask, keys:[{t:0, x:0.3}, {t:2, x:0.7}]}animates one (keys:nullstops it);{op:"removeMask", id, mask}deletes one.props.maskswritten throughaddClip/updateClipis validated the same way. Bad keys, shapes or values refuse the whole patch. Locks apply (force:trueas elsewhere).fablecut_scopes {time, mask:{clip}}measures them: the % of the clip's picture its masks keep (the feathered matte, measured alone) and the % of the frame the masked clip covers. The compact project view lists each clip's masks as[2 masks: ellipse feather 40, rect subtract].
Recipes: spotlight - a feathered ellipse on the clip; split screen - two clips on V1 / V2, a rect on the top one covering its half; cut a logo out of the background - a bezier around it, feather 2–4; reveal - a rect whose w (or x) keys from 0 to full; effects only on the face - an adjustment layer with a feathered ellipse, keyed to follow it; vignette through an adjustment layer - an inverted ellipse with feather:200 and the layer's brightness down.