fablecut 1.12.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +228 -6
- package/README.md +22 -8
- package/app.js +1303 -25
- package/color.js +47 -14
- package/edit-ops.js +25 -4
- package/export-jobs.js +8 -5
- package/index.html +10 -2
- package/mask.js +467 -0
- package/mcp-server.js +207 -7
- package/package.json +1 -1
- package/server.js +22 -1
- package/style.css +11 -0
- package/tracker.js +253 -0
package/CLAUDE.md
CHANGED
|
@@ -37,7 +37,10 @@ Every Claude Code session then has these tools:
|
|
|
37
37
|
- `fablecut_export` — render the timeline to a file in `exports/` with the editor's own
|
|
38
38
|
Fast export (open tab, or headless Chrome / Edge). See "Export" below.
|
|
39
39
|
- `fablecut_scopes` — measure the graded picture at a moment (levels, clipping, colour
|
|
40
|
-
cast), as the editor's scopes see it
|
|
40
|
+
cast), as the editor's scopes see it; also what a grade layer or a clip's masks
|
|
41
|
+
select. See "Color" and "Masks" below.
|
|
42
|
+
- `fablecut_track` — motion tracking: follow a region of a video clip, store it as
|
|
43
|
+
a track, and make a mask or another clip follow it. See "Tracking" below.
|
|
41
44
|
|
|
42
45
|
### Token-efficient editing (important for agents)
|
|
43
46
|
|
|
@@ -313,7 +316,8 @@ Examples in `library/svg/`: `sparkles.svg` (loop), `lower-third.svg`,
|
|
|
313
316
|
| `scale` | 1 | |
|
|
314
317
|
| `rotation` | 0 | degrees |
|
|
315
318
|
| `opacity` | 1 | 0–1 |
|
|
316
|
-
| `blend` | "normal" |
|
|
319
|
+
| `blend` | "normal" | how the clip lays over what is under it (see Track mattes and blending) |
|
|
320
|
+
| `matte` · `matteTrack` | — | a track matte (see Track mattes and blending) |
|
|
317
321
|
|
|
318
322
|
**Layout** (video/image/svg):
|
|
319
323
|
| prop | default | notes |
|
|
@@ -424,6 +428,10 @@ intensity. Keyframe/transition it like any clip. Put it on V2/V3 above the
|
|
|
424
428
|
footage. Example: 0.3 s impact shake over everything =
|
|
425
429
|
`{kind:"adjust", track:"V3", duration:0.3, props:{shake:18}}`.
|
|
426
430
|
|
|
431
|
+
**Masks** (`masks`, video/image/svg/text/adjust): shapes that cut what the clip
|
|
432
|
+
shows — rect, ellipse, bezier, free-hand; feather, expand, invert, add /
|
|
433
|
+
subtract / intersect, keyframes. See "Masks" below.
|
|
434
|
+
|
|
427
435
|
**Animatable props** (usable in `keyframes`): x, y, scale, rotation, opacity,
|
|
428
436
|
volume, pan, duck, speed, brightness, contrast, saturation, hue, blur, grayscale, sepia,
|
|
429
437
|
invert, temperature, tint, vignette, cornerRadius, shake, rgbSplit, grain,
|
|
@@ -619,12 +627,12 @@ each one's qualifier looks at the picture as it reaches that layer.
|
|
|
619
627
|
| `qualifier.hue` | `[centre°, width°, soft°]` — hues within ±width/2 of the centre, easing out over `soft`; wraps through red. Greys carry no hue, so a hue range leaves them out |
|
|
620
628
|
| `qualifier.sat` · `qualifier.luma` | `[low, high, soft]` on 0…1 — saturation (HSV) / Rec.709 luma between low and high |
|
|
621
629
|
| `qualifier.invert` | select everything else |
|
|
622
|
-
| `mask.shape` | `ellipse` · `rect` · `poly` |
|
|
630
|
+
| `mask.shape` | `ellipse` · `rect` · `poly` · `bezier` (or `freehand` with a `stroke`, fitted into a bezier — see "Masks") |
|
|
623
631
|
| `mask.x` · `mask.y` | centre, as fractions of the clip's picture (0…1, y down) |
|
|
624
632
|
| `mask.w` · `mask.h` | size, fractions of the picture's width / height (ellipse, rect) |
|
|
625
633
|
| `mask.rotation` | degrees, clockwise |
|
|
626
634
|
| `mask.feather` | soft edge, a fraction of the picture's height (0…0.5), centred on the outline |
|
|
627
|
-
| `mask.points` | poly: 3–16 `[dx, dy]` corners around `x, y` (fractions of width / height) |
|
|
635
|
+
| `mask.points` | poly: 3–16 `[dx, dy]` corners around `x, y` (fractions of width / height); bezier: 3–24 anchors `[dx, dy]` or `[dx, dy, inX, inY, outX, outY]` with curve handles |
|
|
628
636
|
| `mask.invert` | grade outside the shape |
|
|
629
637
|
| `mask.keys` | animate it: `[{t, x?, y?, w?, h?, rotation?, feather?, 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) |
|
|
630
638
|
|
|
@@ -639,8 +647,9 @@ curves edit that layer, and three more sections appear: the layer's name,
|
|
|
639
647
|
reorder, **Delete**; **Qualifier** — **Pick** then click a colour in the
|
|
640
648
|
monitor to select its hue, saturation and luma, then tune the ranges; and
|
|
641
649
|
**Mask** — pick a shape and drag it on the monitor (inside moves it, the
|
|
642
|
-
handles resize it, the knob rotates it, Shift snaps to 15°; on a poly
|
|
643
|
-
Ctrl-click adds a point and double-click removes one)
|
|
650
|
+
handles resize it, the knob rotates it, Shift snaps to 15°; on a poly or
|
|
651
|
+
bezier, Ctrl-click adds a point and double-click removes one), or **Draw** a
|
|
652
|
+
free-hand outline on the monitor (it becomes a bezier). **◆ Key** keys the
|
|
644
653
|
shape at the playhead; once it has keys, every change to the shape keys.
|
|
645
654
|
|
|
646
655
|
**Wheel colours.** A wheel's `r, g, b` normally carry no brightness: they are a
|
|
@@ -703,6 +712,219 @@ other shot of the scene until its median and cast land near the hero's. In the
|
|
|
703
712
|
editor, **Copy** / **Paste** on the Color tab pastes one clip's grade onto every
|
|
704
713
|
selected clip.
|
|
705
714
|
|
|
715
|
+
### Masks
|
|
716
|
+
|
|
717
|
+
A clip's masks cut what it shows: only the parts the masks keep reach the
|
|
718
|
+
frame, so a clip can be isolated, revealed or cut through, and anything under
|
|
719
|
+
it shows in the gaps. They live in `props.masks` on any video, image, svg,
|
|
720
|
+
text or adjustment clip. On an adjustment layer they limit where its effects
|
|
721
|
+
and grade apply. They run in preview and export alike. The clip draws as usual,
|
|
722
|
+
the masks cut it, and then its `opacity` and `blend` composite it.
|
|
723
|
+
|
|
724
|
+
```jsonc
|
|
725
|
+
"masks": [
|
|
726
|
+
{ "name": "Subject", "shape": "ellipse", "x": 0.52, "y": 0.45, "w": 0.4, "h": 0.7, "feather": 40 },
|
|
727
|
+
{ "name": "Hole", "shape": "rect", "mode": "subtract", "x": 0.6, "y": 0.4, "w": 0.1, "h": 0.1 },
|
|
728
|
+
{ "shape": "bezier", "x": 0.3, "y": 0.7, "expand": 8,
|
|
729
|
+
"points": [[0, -0.1], [0.12, 0.08, 0, -0.05, 0, 0.05], [-0.12, 0.08]],
|
|
730
|
+
"keys": [{ "t": 0, "x": 0.3 }, { "t": 2, "x": 0.6, "ease": "linear" }] }
|
|
731
|
+
]
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
| key | default | does |
|
|
735
|
+
|---|---|---|
|
|
736
|
+
| `shape` | — | `rect` · `ellipse` · `bezier` (write `freehand` with a `stroke` to have one drawn for you) |
|
|
737
|
+
| `x` · `y` | 0.5 | centre, as fractions of the clip's picture (0…1, y down) |
|
|
738
|
+
| `w` · `h` | 0.5 | size, fractions of the picture's width / height (rect, ellipse) |
|
|
739
|
+
| `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 |
|
|
740
|
+
| `stroke` | — | freehand only: `[[u, v], …]` picture fractions along an outline; it is simplified and stored as an editable `bezier` |
|
|
741
|
+
| `scale` · `rotation` | 1 · 0 | about the centre; degrees clockwise |
|
|
742
|
+
| `mode` | `add` | how this mask combines with the ones before it: `add` · `subtract` · `intersect` · `difference` |
|
|
743
|
+
| `invert` | false | use everything outside the shape |
|
|
744
|
+
| `opacity` | 1 | 0…1, how strongly this mask counts |
|
|
745
|
+
| `feather` | 0 | soft edge, project pixels, centred on the outline |
|
|
746
|
+
| `expand` | 0 | grow (+) or shrink (−) the outline, project pixels |
|
|
747
|
+
| `name` · `on` | — | a label; `on:false` turns the mask off |
|
|
748
|
+
| `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 |
|
|
749
|
+
|
|
750
|
+
Masks combine bottom-up (first in the list first). The first one starts from
|
|
751
|
+
nothing when it adds and from the whole picture otherwise, so a lone
|
|
752
|
+
`subtract` cuts a hole in a full picture. At most 8 masks per clip.
|
|
753
|
+
|
|
754
|
+
The picture a mask lives in is the clip's drawn rectangle for video, image
|
|
755
|
+
and svg (after fit and crop), the text block for text, and the whole canvas
|
|
756
|
+
for an adjustment layer. Masks follow the clip when it is moved, scaled,
|
|
757
|
+
rotated or flipped, and keep the clip's keyframes.
|
|
758
|
+
|
|
759
|
+
In the editor, the **Masks** section of the Inspector has **+ Rect**,
|
|
760
|
+
**+ Ellipse**, **Pen** (click points on the monitor, drag while placing one to
|
|
761
|
+
pull curve handles, click the first point or press Enter to close) and
|
|
762
|
+
**Draw** (drag a free-hand outline). **Matte** shows the clip's matte in the
|
|
763
|
+
monitor (white = visible). Pick a mask's chip to edit it: mode, **Invert**,
|
|
764
|
+
the sliders, ↑ ↓ to reorder, **Copy**, **Delete**, and on the monitor, drag
|
|
765
|
+
inside to move it, the edge handles to resize it and the knob to rotate it
|
|
766
|
+
(Shift snaps to 15°). On a bezier, drag a point to move it, drag its handles
|
|
767
|
+
to curve it (Alt breaks the pair), Alt-drag a point to pull fresh handles,
|
|
768
|
+
Ctrl-click the outline to add a point, and double-click a point to remove
|
|
769
|
+
it. **◆ Key** keys the whole mask at the playhead; once it has keys, every
|
|
770
|
+
change keys. Esc steps back (point, then mask).
|
|
771
|
+
|
|
772
|
+
**Agents** edit masks with patch ops:
|
|
773
|
+
|
|
774
|
+
- `{op:"setMask", id, set:{shape:"ellipse", x:0.5, y:0.45, w:0.4, h:0.7, feather:40}}`
|
|
775
|
+
adds a mask (no `mask`, an index one past the end or a new name adds one; a
|
|
776
|
+
new mask needs `shape`). `{op:"setMask", id, mask:"Subject", set:{x:0.6}}`
|
|
777
|
+
edits one, by index (0 = first) or name, merging key by key (`null` resets a
|
|
778
|
+
key). `replace:true` starts it over, keeping its name. `ids:[…]` edits several clips.
|
|
779
|
+
- A drawn outline: `set:{shape:"freehand", stroke:[[0.4, 0.3], [0.6, 0.32], …]}`.
|
|
780
|
+
It is stored as an editable bezier.
|
|
781
|
+
- `{op:"setMaskKeys", id, mask, keys:[{t:0, x:0.3}, {t:2, x:0.7}]}` animates
|
|
782
|
+
one (`keys:null` stops it); `{op:"removeMask", id, mask}` deletes one.
|
|
783
|
+
- `props.masks` written through `addClip` / `updateClip` is validated the same
|
|
784
|
+
way. Bad keys, shapes or values refuse the whole patch. Locks apply
|
|
785
|
+
(`force:true` as elsewhere).
|
|
786
|
+
- `fablecut_scopes {time, mask:{clip}}` measures them: the % of the clip's
|
|
787
|
+
picture its masks keep (the feathered matte, measured alone) and the % of
|
|
788
|
+
the frame the masked clip covers. The compact project view lists each
|
|
789
|
+
clip's masks as `[2 masks: ellipse feather 40, rect subtract]`.
|
|
790
|
+
|
|
791
|
+
Recipes: **spotlight** — a feathered ellipse on the clip; **split screen** —
|
|
792
|
+
two clips on V1 / V2, a `rect` on the top one covering its half; **cut a
|
|
793
|
+
logo out of the background** — a bezier around it, `feather` 2–4;
|
|
794
|
+
**reveal** — a rect whose `w` (or `x`) keys from 0 to full; **effects only
|
|
795
|
+
on the face** — an adjustment layer with a feathered ellipse, keyed to follow
|
|
796
|
+
it; **vignette through an adjustment layer** — an inverted ellipse with
|
|
797
|
+
`feather:200` and the layer's `brightness` down.
|
|
798
|
+
|
|
799
|
+
### Track mattes and blending
|
|
800
|
+
|
|
801
|
+
A **track matte** cuts a clip with the picture on another track: where that
|
|
802
|
+
picture is opaque (alpha) or bright (luma), the clip shows. Set it on the
|
|
803
|
+
clip being cut, the fill:
|
|
804
|
+
|
|
805
|
+
| prop | does |
|
|
806
|
+
|---|---|
|
|
807
|
+
| `matte` | `alpha` · `alpha-inverted` · `luma` · `luma-inverted`. Alpha keeps the clip where the matte's pixels are opaque, luma where they are bright (white = shows, black = gone, Rec. 709 weights). The inverted modes keep the opposite |
|
|
808
|
+
| `matteTrack` | the video track the matte comes from. Default: the video track directly above the clip (V2 for a clip on V1) |
|
|
809
|
+
|
|
810
|
+
The matte track does not draw into the frame while a clip on screen uses it;
|
|
811
|
+
it only cuts. Its clips keep their own transform, keyframes, opacity, masks
|
|
812
|
+
and effects, so the matte can move, scale and animate on its own. When the
|
|
813
|
+
matte track has nothing at that moment, `alpha` / `luma` show nothing of the
|
|
814
|
+
clip and the inverted modes show all of it. Track mattes and masks combine:
|
|
815
|
+
the matte cuts the clip, then its masks cut what is left, then `opacity` and
|
|
816
|
+
`blend` composite it. A clip used as a matte is drawn without its own track
|
|
817
|
+
matte. Audio clips take neither.
|
|
818
|
+
|
|
819
|
+
`blend` is how a clip lays over what is under it: `normal` · `multiply` ·
|
|
820
|
+
`screen` · `overlay` · `darken` · `lighten` · `color-dodge` · `color-burn` ·
|
|
821
|
+
`hard-light` · `soft-light` · `difference` · `exclusion` · `hue` ·
|
|
822
|
+
`saturation` · `color` · `luminosity` · `lighter` (add). Blending happens after
|
|
823
|
+
masks and mattes, so a masked clip only blends where it is kept.
|
|
824
|
+
|
|
825
|
+
In the editor, **Track matte** and **Matte track** sit under **Blend** in the
|
|
826
|
+
Inspector's Transform section (the Adjustment layer section for an adjustment
|
|
827
|
+
layer). The timeline marks a clip with a track matte ◐ and shows the clips
|
|
828
|
+
that serve as its matte hatched, labelled **Matte**.
|
|
829
|
+
|
|
830
|
+
**Agents:** `{op:"setMatte", id, matte:"luma"}` (or `ids:[…]`; `track:"V3"`
|
|
831
|
+
picks the matte track, `track:null` goes back to the one above;
|
|
832
|
+
`matte:null` removes it). `blend`, `matte` and `matteTrack` written through
|
|
833
|
+
`addClip` / `updateClip` are validated too. `fablecut_scopes` lists each clip
|
|
834
|
+
on screen with its `matte` (e.g. `luma from V2`), `blend`, and whether it is a
|
|
835
|
+
matte itself.
|
|
836
|
+
|
|
837
|
+
Recipes: **text filled with video** — the text on V2, the video on V1 with
|
|
838
|
+
`matte:"alpha"`; **a shape reveal** — an svg or a masked solid on V2 whose
|
|
839
|
+
scale keys up, the shot on V1 with `matte:"alpha"`; **light leaks / film
|
|
840
|
+
burn** on V2 with `blend:"screen"`; **a grade only in the bright areas** — an
|
|
841
|
+
adjustment layer with `matte:"luma"` over a copy of the shot;
|
|
842
|
+
**a cut-out through a texture** — `luma-inverted` against a black-and-white
|
|
843
|
+
texture.
|
|
844
|
+
|
|
845
|
+
### Tracking
|
|
846
|
+
|
|
847
|
+
Motion tracking follows something in a video clip frame by frame: a corner, a
|
|
848
|
+
logo, a face, a sign. The result is a **track** stored on the clip, and masks
|
|
849
|
+
and other clips **follow** it by having it written into their keys. Rendering
|
|
850
|
+
never reads a track, so a followed mask or title renders and exports exactly
|
|
851
|
+
like a hand-keyed one, and you can edit its keys afterwards.
|
|
852
|
+
|
|
853
|
+
```jsonc
|
|
854
|
+
"tracks": [
|
|
855
|
+
{ "name": "Logo", "kind": "point", "w": 0.08, "h": 0.14,
|
|
856
|
+
"samples": [[0, 0.31, 0.42, 1, 0, 1], [0.0333, 0.312, 0.421, 1, 0, 0.98]] }
|
|
857
|
+
]
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
| key | does |
|
|
861
|
+
|---|---|
|
|
862
|
+
| `name` | how masks, clips and agents refer to it (default `Track n`, or the mask's name) |
|
|
863
|
+
| `kind` | `point` (position) or `box` (position, size and rotation were followed) |
|
|
864
|
+
| `w` · `h` | the region that was matched, fractions of the clip's picture |
|
|
865
|
+
| `samples` | one per frame: `[t, x, y, s, r, q]`. `t` is seconds from the clip's start, `x, y` is the centre (fractions of the picture, like masks), `s` is the scale and `r` the rotation (°) relative to the first sample, `q` is the match quality 0…1 |
|
|
866
|
+
|
|
867
|
+
The tracker matches a small greyscale template of the region (normalized
|
|
868
|
+
cross-correlation, sub-pixel, optionally over scale and rotation) and keeps
|
|
869
|
+
the template fresh while anchoring it to the first frame so it does not
|
|
870
|
+
drift. It stops where the match quality drops below 0.45 (the region was
|
|
871
|
+
covered, left the frame or changed too much) and keeps what it tracked up to
|
|
872
|
+
there. Pick regions with detail: corners, text, edges. Flat sky or a blank
|
|
873
|
+
wall can't be tracked. A track without scale follows position only: if the
|
|
874
|
+
thing grows, shrinks or turns noticeably, turn on Scale / Rotate (`scale` /
|
|
875
|
+
`rotation`), or the match fades and the track stops early. Tracks are stored in clip time, so they move with the clip and follow
|
|
876
|
+
trims and splits (re-track after changing its speed).
|
|
877
|
+
|
|
878
|
+
In the editor:
|
|
879
|
+
|
|
880
|
+
- **Mask tracking.** Select a mask on a video clip. Under its mode row,
|
|
881
|
+
**◀ Back** and **On ▶** follow what the mask covers from the playhead to
|
|
882
|
+
the clip's start or end, and key the mask's `x` / `y`. Turn on **Scale**
|
|
883
|
+
and **Rotate** to key those too. The keys are linear and simplified (a key
|
|
884
|
+
only where the motion turns, within ~1.5 px). Keys the mask had in that range lose their
|
|
885
|
+
position and keep everything else.
|
|
886
|
+
- **Point tracking.** The Inspector's **Tracking** section (video clips):
|
|
887
|
+
**+ Track point**, then click the spot on the monitor. It tracks from the
|
|
888
|
+
playhead to the clip's end. **Region** sets the matched area (% of the
|
|
889
|
+
picture's width). Pick a track's chip to see its path and region on the
|
|
890
|
+
monitor, **◀ Track back** / **Track on ▶** to extend it from the playhead,
|
|
891
|
+
and **Delete** it.
|
|
892
|
+
- **Attach a clip.** With a track picked, choose a clip in **Attach**
|
|
893
|
+
(any visual clip that overlaps it in time) and press **Attach to the track**. The clip
|
|
894
|
+
gets `x` / `y` keyframes (plus `scale` / `rotation` with those toggles on)
|
|
895
|
+
that ride on the track and keep it where it is at the playhead. Stickers,
|
|
896
|
+
titles, a blur box or a highlight then stay pinned to the moving thing.
|
|
897
|
+
- Tracking runs from a private copy of the video, so the monitor does not
|
|
898
|
+
move. Progress shows in the Inspector, and **Esc** stops it and keeps what
|
|
899
|
+
it has. Each finished track is one undo step.
|
|
900
|
+
|
|
901
|
+
**Agents:** `fablecut_track` runs the tracker in the editor (an open tab, else
|
|
902
|
+
headless Chrome / Edge) and saves the result:
|
|
903
|
+
|
|
904
|
+
- `{clip, point:{x:0.62, y:0.4}, at:12}` follows a spot from `at` to the
|
|
905
|
+
clip's end. `region:{x, y, w, h}` gives the area instead, `size` sets a
|
|
906
|
+
point's region (default 0.08 of the width), `direction:"backward"|"both"`
|
|
907
|
+
and `to` (timeline seconds) set the range, and `scale` / `rotation` follow
|
|
908
|
+
those too.
|
|
909
|
+
- `apply:{mask:"Face"}` bakes the result into that mask's keys. Leave out
|
|
910
|
+
`point` / `region` and the mask's own outline is what gets followed.
|
|
911
|
+
- `apply:{clip:"c_sticker", scale?, rotation?, at?}` pins another clip to
|
|
912
|
+
the track.
|
|
913
|
+
- `name` names the track. Passing an existing name with `apply` and no
|
|
914
|
+
region re-applies the stored track without tracking again.
|
|
915
|
+
- The reply gives the range, the match quality (min / mean; ≥ 0.8 is solid),
|
|
916
|
+
where it was lost, and what was keyed.
|
|
917
|
+
- `{op:"removeTrack", id, track}` deletes a stored track; what followed it
|
|
918
|
+
keeps its keys. The compact project view lists tracks as
|
|
919
|
+
`[tracks: "Logo" point 0.00–4.20 s (127 samples)]`, never their samples.
|
|
920
|
+
|
|
921
|
+
Recipes: **a title that follows a car** — track a point on the car, attach
|
|
922
|
+
the title; **blur a face or a plate** — an ellipse mask on a blurred copy of
|
|
923
|
+
the shot on the track above, then `apply:{mask:"Face"}`; **a screen replacement** —
|
|
924
|
+
track the screen with Scale and Rotate on and attach the new picture, cropped
|
|
925
|
+
to fit; **a highlight that stays on a UI element** in a screen recording —
|
|
926
|
+
track the button, attach a rect svg.
|
|
927
|
+
|
|
706
928
|
### Semantics
|
|
707
929
|
|
|
708
930
|
- Rendering order: V1 is drawn first, then V2, V3, … on top. SVG/image/text clips
|
package/README.md
CHANGED
|
@@ -178,15 +178,29 @@ same time.
|
|
|
178
178
|
pivot, soft rolloff and saturation, plus **curves** — luma and R / G / B,
|
|
179
179
|
hue vs hue, hue vs saturation, hue vs luma and saturation vs luma, with a
|
|
180
180
|
picker that marks a colour from the monitor, and **layers** (secondaries):
|
|
181
|
-
a correction limited by an HSL **qualifier** and / or an ellipse, rect
|
|
182
|
-
polygon **mask** (feathered, invertible, keyframable,
|
|
183
|
-
monitor), with a matte view. Copy / paste a grade across shots.
|
|
181
|
+
a correction limited by an HSL **qualifier** and / or an ellipse, rect,
|
|
182
|
+
polygon, bezier or free-hand **mask** (feathered, invertible, keyframable,
|
|
183
|
+
dragged on the monitor), with a matte view. Copy / paste a grade across shots.
|
|
184
184
|
Agents grade with the `setGrade` patch op and read the result as numbers
|
|
185
185
|
with `fablecut_scopes` (levels, clipping, colour cast)
|
|
186
186
|
- Quick filter sliders: brightness/contrast/saturation/hue, **temperature & tint**,
|
|
187
187
|
blur, grayscale/sepia/invert, **vignette**, animated **film grain**
|
|
188
|
-
-
|
|
188
|
+
- 17 blend modes (screen, multiply, overlay, color-burn, exclusion, hue,
|
|
189
|
+
luminosity…), fit modes (contain/cover/stretch),
|
|
189
190
|
per-edge cropping, corner radius, flip H/V
|
|
191
|
+
- **Masks** — isolate any part of a clip (video, image, SVG, text or an
|
|
192
|
+
adjustment layer): rectangle, ellipse, **bezier pen** and **free-hand**
|
|
193
|
+
shapes, several per clip, combined with add / subtract / intersect /
|
|
194
|
+
difference, each with feather, expansion, invert and opacity, all
|
|
195
|
+
keyframable (outlines morph). Draw and edit them on the monitor, with a
|
|
196
|
+
matte view. Agents use the `setMask` patch op and measure with `fablecut_scopes`
|
|
197
|
+
- **Motion tracking** — follow a point or a region (with its scale and
|
|
198
|
+
rotation) through a video clip, then make a mask follow it or pin a title,
|
|
199
|
+
sticker or any clip to it; the result is ordinary editable keys. Agents use
|
|
200
|
+
`fablecut_track`
|
|
201
|
+
- **Track mattes** — cut a clip with the picture on the track above by its
|
|
202
|
+
alpha or its luma (inverted or not): text filled with video, shape reveals,
|
|
203
|
+
texture cut-outs. The matte track hides itself. Agents use `setMatte`
|
|
190
204
|
- **Chroma key** (green screen) with tolerance/softness + spill suppression
|
|
191
205
|
- **AI background removal** (person cut-out, in-browser via MediaPipe)
|
|
192
206
|
|
|
@@ -379,7 +393,7 @@ Three equivalent control surfaces:
|
|
|
379
393
|
`fablecut_get_project`, `fablecut_set_project`, `fablecut_patch_project`,
|
|
380
394
|
`fablecut_import_media`, `fablecut_analyze_reference`,
|
|
381
395
|
`fablecut_encode_profiles`, `fablecut_normalize_audio`, `fablecut_auto_duck`,
|
|
382
|
-
`fablecut_denoise`, `fablecut_export`, `fablecut_scopes`.
|
|
396
|
+
`fablecut_denoise`, `fablecut_export`, `fablecut_scopes`, `fablecut_track`.
|
|
383
397
|
|
|
384
398
|
FableCut is also published on the **official MCP registry** as
|
|
385
399
|
[`io.github.ronak-create/fablecut`](https://registry.modelcontextprotocol.io/v0/servers?search=fablecut)
|
|
@@ -555,11 +569,11 @@ examples in [`library/svg/`](library/svg/).
|
|
|
555
569
|
|
|
556
570
|
## Sponsors
|
|
557
571
|
|
|
558
|
-
<a href="https://fluxionai.
|
|
559
|
-
<img src="docs/sponsors/
|
|
572
|
+
<a href="https://fluxionai.space/register?source=github&campaign=github-sidrune-fablecut&promo=SDRFABLECUT" target="_blank" rel="noopener noreferrer sponsored">
|
|
573
|
+
<img src="docs/sponsors/sidrune-ai-banner.png" alt="Sidrune AI — one API for GPT, Claude and other leading AI models" width="640">
|
|
560
574
|
</a>
|
|
561
575
|
|
|
562
|
-
**[
|
|
576
|
+
**[Sidrune AI](https://fluxionai.space/register?source=github&campaign=github-sidrune-fablecut&promo=SDRFABLECUT)** — One API for GPT, Claude, and other leading AI models. Sign up and get $3 in API credit.
|
|
563
577
|
|
|
564
578
|
## Community
|
|
565
579
|
|