Render Settings: field render with 3:2 pulldown phases, effects/solo/guide
layer/color depth/frame blending/motion blur overrides, custom time sampling
(duration), storage overflow through a quota hook. Output Module: crop
(edges or region of interest), resize (presets, lock aspect, quality),
straight/premultiplied/alpha-only channels, post-render actions, include
project link, audio channels and PCM formats, WebM bitrate and key frame
interval. Render Settings / Output Module templates with built-ins and
defaults per slot (Edit > Templates dialogs), render logs next to the
output, Notify on completion. All through renderQueue.* commands and
persisted in the project.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ui-egui: scriptui_view draws script windows at engine layout bounds; PanelKind::ScriptPanel; File ▸ Scripts and Window menu list scripts/panels (egui + native menus)
- examples/plugins/posterize-bands (WebAssembly, API v1); host plug-in tests; desktop loads <config>/Plug-ins
- MCP: script_ui and history tools; docs/plugins.md, agents.md, parity, architecture, ATTRIBUTION
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Display Color Space setting joins the live list; View3D::Default maps to view.3d.default for
the Assign Shortcut submenu; stub tests use the stubs that remain.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reconciled with main's keyframe labels (same Keyframe::label field; keys.setLabel and
keys.selectLabelGroup from main are kept, M14.5's duplicates removed; Edit ▸ Label on
selected keys delegates to the label helper), proxies (RenderOpts::proxy next to
nested_switches/draft_shadows), offloaded renders (Work carries nested_switches), wasm
audio pump (preview mix rate), variable font axes and mask feather points.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Lumetri: HSL Secondary key/refine/correction with Show Mask, Hue vs Sat/Hue/Luma,
Luma vs Sat, Sat vs Sat and per-channel RGB curves, High Dynamic Range (HDR White /
Specular), Input LUT and Look (custom .cube + built-in looks).
- Hue/Saturation: Channel Control with Reds..Magentas ranges (range + fall-offs).
- Levels: Channel popup and Red/Green/Blue/Alpha controls; Curves: Channel parameter.
- catalog::param_shown: Effect Controls shows only what a popup selects.
- Timewarp Pixel Motion: block-matching flow (raster::flow::block_flow_window) with
Vector Detail, Smoothing, Error Threshold, Block Size, Weighting, Correct Luminance,
Filtering, Build From One Image; Matte Layer/Channel, Warp Layer, Show, Source Crops.
- GPU falls back to CPU when channel/range controls are used.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Text: text.animatorFontAxes (replaces the stub) lists the layer font's
variation axes (skrifa) or adds an animator property that offsets one axis
(weighted by the selectors, from the axis default); the renderer redraws each
character's outline at its design-space position (cached per location). The
Timeline's Animate: menu lists the font's axes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Viewer: the region of interest has corner and edge handles that resize it
from the opposite corner/edge; Pan Behind snaps the anchor point (layer
features, guides, grid) and measures from the press point (it lagged by the
drag threshold); Choose Grid and Guide Options > 3D Reference Axes toggles a
world-axis triad seen through the view's camera (Settings > 3D).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ANM-4: the Graph Editor's reference graph and key snapping already existed;
Snap now also targets comp and layer markers, layer in/out points and the
work area (graph_tools::comp_snap_times), with a unit test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LYR-9: Layer > Layer Styles > Layer Style Options... (layer.style.options)
and choosing a style from that menu open a Layer Style dialog: style list
with check boxes (Blending Options first) and the selected style's controls
built from its layerStyles properties, edited live through prop.set (one
undo step per control); Cancel rolls back everything done since it opened.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 3D Camera Tracker analysis joins the offloaded jobs. The disk cache stays off in the
browser (std::env::temp_dir panics on wasm32 once a config store exists).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Text: vertical type turns Roman characters on their side (CJK stays
upright) unless Standard Vertical Roman Alignment is on; Tate-Chu-Yoko sets
selected characters horizontally in a one-em cell of the column (layer.setText
tateChuYoko / verticalRomanUpright, Character panel toggles). A Left-to-Right
paragraph is now forced LTR instead of auto-detected. The editing caret follows
animators and text on a path (render::text::caret_maps). Lottie export writes
per-character style runs as index-unit range animators.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Interface: Timeline outline columns wider than the pane scroll horizontally
(Shift+wheel/trackpad, scroll bar above the footer; headers clipped); the
Project panel's optional columns scroll under the frozen Name/Label columns.
ANM-1: keyframe colour labels (keys.setLabel, Label submenu, tinted key
icons) and Edit > Select Keyframe Label Group on selected/all layers and
visible keyframes (keys.selectLabelGroup replaces the stub). Alt-drag time
scaling of key groups already existed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Persistence: settings, shortcuts, recent projects, imported media, saved projects and
auto-saves live in OPFS (IndexedDB fallback) through an in-memory mirror flushed in the
background (apps/effectcraft-web/src/store.rs, persist.rs); ConfigStore gains FileOps so
auto-save / recovery work in the browser store; the session snapshot restores the last
project + editor state on reload; File > Open Recent works from storage.
- Audio: Web Audio output (AudioWorklet, ScriptProcessor fallback) fed by AudioPlayback::pump
on wasm32; A/V sync from AudioContext.currentTime; meters; unlock on first gesture.
- Background jobs: engine::offload (WorkerRequest/WorkerReply protocol, Offload trait,
run_request); Render Queue, tracker, mask tracker, Warp Stabilizer and Roto Freeze run in Web
Workers (a second engine instance on the shared compiled module), progress streamed back;
cancel terminates the worker.
- GPU: WebGPU viewer frames drawn straight from the compositor's texture (gpu_display on
wasm32 when the viewer draws plainly); async readback (Gpu::read_display_async) for pixels.
- PWA: manifest, service worker precaching the build (xtask fills list/version), icons copied
from assets/app-icon; COOP/COEP kept from cached responses; offline reload works.
- window.effectcraft: saveToBrowser, listStored, removeStored, flush; info() reports storage,
audio, gpu, workers.
- Tests: native store + protocol + offload (render, track, cancel) tests; smoke.mjs extended
(GPU path, worker render responsiveness, audio gesture + playback, reload persistence,
Open Recent, offline reload).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Window > Essential Graphics: Primary comp, Solo Supported Properties (timeline filter),
template name, typed controls editing the source properties, drag a property name from the
timeline onto the list, rename/reorder/remove, Add Formatting (group, comment), Media
Replacement, Export Template, and the selected instance's Essential Properties with Revert /
Push. The comp viewer shows an expression error bar (click to reveal); the expression editor's
f button opens the categorised Expression Language menu. Project panel proxy switch; Interpret
Footage dialog gains Guess, matte colour, Invert Alpha, Separate Fields, Linear Light, Proxy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shapes (SHP-2): Stroke Taper (pixels/percent start/end length, width, ease) and
Wave (amount, pixels/cycles, wavelength, phase) rendered as a variable-width
outline; Dash 2/Gap 2/Dash 3/Gap 3 (shape.dashes.add/remove, timeline +/-
buttons); radial gradient Highlight Length/Angle as a focal gradient.
Masks (MSK-1): mask feather points on the Mask Path (mask.featherPoint.*,
Mask Feather tool add/drag), per-point signed radius and tension, rendered
from the signed distance to the path; carried through vertex edits.
Motion blur (LYR-10): Adaptive Sample Limit comp setting; 2D layers take one
sample per pixel of shutter travel between Samples Per Frame and the limit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Items (footage and comps) carry a proxy rendered in their place at the source's size when
its switch and Render Settings > Proxy Use allow it; Create Proxy queues a half-resolution
render whose post-render action attaches it. Interpret Footage gains Separate Fields
(upper/lower first, fields become frames at twice the rate), Guess alpha with matte colour,
explicit matte colour, Invert Alpha, Interpret As Linear Light; non-square footage, solids
and precomps are stretched by their pixel aspect in the comp. The four proxy stubs are gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sampleImage renders the sampled layer through the evaluating renderer's footage source
(EvalCtx::footage), cached per thread and frame. File > Import reads .json/.csv/.tsv as data
footage kept in the project. expr.errors collects failing expressions for the error bar;
expr.languageMenu lists the categorised Expression Language menu. Marker keys expose
protectedRegion and cue points; colorDepth, timeToFeetAndFrames, comp.activeCamera.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>