Effects
79 effects, from color to blur to chroma key.
project.dispatch({
type: "effect/add",
payload: { clipId: "intro", kind: "colorAdjust", effectId: "grade", params: { contrast: 0.2, saturation: 0.25 } },
});
// Omitted params take their defaults. This keys out #00ff00:
project.dispatch({ type: "effect/add", payload: { clipId: "webcam", kind: "chromaKey" } });Each visual clip has an effect stack. Effects render in array order, before the clip's transform. Preview, browser export, worker export, server export and stills all render the built-in effects.
Commands
// Merge new params into the current ones (wire this to a slider)
project.dispatch({ type: "effect/update", payload: { clipId: "intro", effectId: "grade", params: { saturation: 0.4 } } });
// Turn off without losing settings
project.dispatch({ type: "effect/update", payload: { clipId: "intro", effectId: "grade", enabled: false } });
// Move to the bottom of the stack, or remove
project.dispatch({ type: "effect/reorder", payload: { clipId: "intro", effectId: "grade", index: 0 } });
project.dispatch({ type: "effect/remove", payload: { clipId: "intro", effectId: "grade" } });| Command | Payload | Notes |
|---|---|---|
effect/add | { clipId, kind, params?, enabled?, index?, effectId? } | Appends unless index is set. effectId is generated if omitted |
effect/update | { clipId, effectId, params?, enabled? } | params merge, then the whole set is validated again |
effect/reorder | { clipId, effectId, index } | 0 renders first |
effect/remove | { clipId, effectId } |
Rejections: unknown-kind, invalid-params (out of range, or a non-integer for an integer param), duplicate-id, effect-not-found.
Each stored effect is { id, kind, enabled, params }, with every param filled in.
Built-in kinds
79 kinds in 7 categories. EFFECT_CATALOG and EFFECT_CATEGORIES hold the same data at runtime.
Category (id) | Count | Kinds |
|---|---|---|
Color (color) | 17 | colorAdjust, mono, invert, warm, cool, hueShift, vibrance, exposure, contrastCurve, gamma, channelSwap, duotone, gradientMap, colorPop, solarize, threshold, posterize |
Film (film) | 21 | sepia, vintage, polaroid, kodachrome, technicolor, thermal, grain, tealOrange, noir, bleachBypass, crossProcess, faded, matte, goldenHour, moonlight, cyberpunk, vaporwave, cyanotype, infrared, lomo, nightVision |
Stylize (stylize) | 14 | pixelate, halftone, dotMatrix, crosshatch, neonEdges, sketch, emboss, sharpen, toon, oilPaint, hexPixelate, retro8bit, dither, frostedGlass |
Glitch & Retro (glitch) | 7 | rgbSplit, scanlines, crt, vhs, glitch, tvStatic, lensFringe |
Blur & Light (light) | 9 | blur, vignette, glow, dreamy, tiltShift, zoomBlur, motionBlur, colorVignette, lightLeak |
Distort (distort) | 8 | fisheye, pinch, swirl, wave, ripple, mirrorX, mirrorY, kaleidoscope |
Frame & Key (frame) | 3 | chromaKey, letterbox, roundedCorners |
Look up a kind's params, ranges and defaults with getEffectInfo:
import { defaultEffectParams, getEffectInfo } from "@miraiclip/core";
getEffectInfo("colorAdjust")?.params.map((p) => p.key); // ["brightness", "contrast", "saturation", "hue"]
defaultEffectParams("chromaKey"); // { color: "#00ff00", similarity: 0.4, smoothness: 0.1, spill: 0.1 }Build an effect picker
The catalog is plain data, so a picker and a properties panel need no hard-coded list.
import { EFFECT_CATALOG, EFFECT_CATEGORIES, getEffectInfo } from "@miraiclip/core";
const groups = EFFECT_CATEGORIES.map((category) => ({
...category,
effects: EFFECT_CATALOG.filter((effect) => effect.category === category.id),
}));
for (const param of getEffectInfo("tiltShift")?.params ?? []) {
if (param.type === "number") {
console.log(param.label, param.min, param.max, param.step, param.default, param.format);
} else {
console.log(param.label, param.default); // "#rrggbb"
}
}EffectInfo field | Meaning |
|---|---|
kind | Command kind |
label | Display name, e.g. "Tilt Shift" |
category | One of the EFFECT_CATEGORIES ids |
params | EffectParamInfo[], in display order |
EffectParamInfo field | Meaning |
|---|---|
key, label | Param name in params, and its display name |
type | "number" or "color" (#rrggbb) |
min, max, step, default | Number params. Commands reject values outside min..max |
format | Display hint: "percent", "int", "deg", "stops" or "decimal". "int" params must be integers |
length | true when the value is a fraction of composition height, not pixels |
getEffectInfo and defaultEffectParams return undefined for custom kinds.
Thumbnails
renderEffectThumbnails (renderer, browser only) applies each kind's real filter to a sample image and returns data URLs.
import { renderEffectThumbnails } from "@miraiclip/renderer";
declare const tiles: Map<string, HTMLElement>;
const thumbnails = await renderEffectThumbnails({
size: 144,
onThumbnail: (kind, dataUrl) => {
const tile = tiles.get(kind);
if (tile) tile.style.backgroundImage = `url(${dataUrl})`;
},
});| Option | Default | Meaning |
|---|---|---|
kinds | Every catalog kind | Built-in or registered custom kinds |
size | 144 | Square size in px |
sample | Built-in sample scene | Any CanvasImageSource, drawn cover-fit |
lengthScale | 3 | Magnifies length params so they read at thumbnail size. 1 is true scale |
type, quality | "image/jpeg" | Image encoding |
onThumbnail(kind, dataUrl) | Called as each one is ready | |
signal | Cancel |
It resolves with a Map of kind to data URL. Kinds that fail to render are skipped.
Notes
- Length params are fractions of composition height, so an effect looks the same in a scaled preview and a full-size export.
- Effect params can't be keyframed. Keyframes animate
x,y,scale,rotation,opacityandvolumeonly. - Effects have no time input:
vhs,glitchandtvStaticare static for a givenseed. - Need a look that isn't built in? Custom effects. Custom effects don't render in worker or server export.