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>
Layer > Camera > Create Stereo 3D Rig (left/right eye comps with expression-linked eye
cameras, Stereo 3D Controls effect, stereo comp through 3D Glasses), Create Orbit Null,
Create Cameras from 3D Model; Layer > Light > Create Lights from 3D Model
(KHR_lights_punctual), Control Light with Camera, Create Environment Light Background
Layer (equirectangular sky drawn through the camera). glTF cameras and punctual lights
are parsed by effectcraft-model.
Advanced 3D: per-sample motion blur over the comp shutter, and blend modes / track
mattes / Preserve Transparency composited through the 2D path in depth order.
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>
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>
3D-1: Classic 3D depth of field renders the camera's Iris Shape (Fast
Rectangle box or Triangle…Decagon polygon), Iris Rotation, Roundness, Aspect
Ratio and Diffraction Fringe as a span-kernel gather blur, with Highlight
Gain/Threshold/Saturation boosting highlights first; tilted layers blur
progressively by per-pixel camera depth. Layer > Camera > Link Focus Distance
to Point of Interest / to Layer (expressions) and Set Focus Distance to Layer
replace the stubs.
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>
Comps expose controls (properties typed as text/color/slider/checkbox/point/angle/dropdown,
Media Replacement, groups, comments); precomp layers get an Essential Properties group whose
edits override per instance (Push to Comp / Revert); templates export/import as an open ZIP
(manifest.json + project subset + media + poster). Stretched precomps keep protected regions
at their original speed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds Review, Learn, Essential Graphics, Color and Undocked Panels to the
built-in workspaces (Libraries, an Adobe service, is left out), lists them all
in Window > Workspace in After Effects' order, and gives each its own layout:
Review (large viewer, Markers and Project), Learn (Default plus the Home
screen with the community links), Essential Graphics (Properties panel full
height, type panels), Color (wide Effect Controls, Info), Undocked Panels
(Composition docked, the other panels floating). Tests check every AE
workspace exists, has its own layout, has each panel once and is in the menu.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Native menu bar (apps/effectcraft, muda, macOS only): the engine's After Effects
menu tree mirrored into NSMenu through a pure, serializable spec
(ui-egui native_menu: submenus, separators, live labels, check marks, enabled
state, Cmd/Ctrl/function-key shortcuts as accelerators, Open Recent). Hide /
Hide Others / Show All are macOS' predefined items (app.hideOthers/app.showAll
are real commands now, via NSApplication); Services added; About, Settings and
Quit dispatch our commands. State is pushed only when the session revision,
selection, history, settings or journal change; structural changes rebuild.
Activations dispatch the same command ids as the in-window bar; Edit
Cut/Copy/Paste/Select All/Undo/Redo act on a focused text field. Settings >
Appearance > Use In-Window Menu Bar on macOS switches back.
Timeline: column visibility from the column header's context menu (A/V
Features, Keys, Label, #, Comment, Switches, Modes, Parent & Link, In, Out,
Duration, Stretch; Source/Layer Name toggle), Comment editing
(layer.setComment), draggable In/Out/Duration cells, Stretch opens Time
Stretch; property search filters layers and reveals matching properties with
their groups; Shift+P/S/R/T/A/E/M/F/L/U add to the revealed properties; UU
reveals all modified properties; Shift-drag in the ruler snaps the CTI to keys,
in/out points, markers and the work area. Commands: timeline.column,
timeline.sourceName, timeline.search, timeline.revealAdd.*.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Advanced 3D comps render their 3D runs as one scene of world-space triangles: model and
primitive layers (meshes, skinning, animation clips by layer time), extruded text/shape
layers, and textured cards for every other layer with their Material Options. Shading is
physically based in linear light: Cook-Torrance GGX + Lambert for parallel/spot/point lights
(AE falloff and cone), ambient lights, image-based light from an Environment light's layer
(equirectangular; cosine irradiance map + roughness mip chain + split-sum BRDF fit), and
PCF shadow maps (spot/parallel/point cube faces). 2x2 SSAA, depth of field as a gather blur
by circle of confusion, back to the working encoding.
The software rasteriser (depth buffer, top-left rule, perspective-correct, opaque visibility
then sorted transparent blending) is the reference and CI path; effectcraft-gpu implements
Accelerator::raster_3d with a wgpu render pipeline (advanced3d.wgsl) and matches it within
tolerance. Environment layers are hidden from both renderers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Liquify stores its strokes as effect data and replays them into a cached
displacement mesh; liquify.stroke / liquify.clear commands for agents.
Rolling Shutter Repair measures motion with effectcraft-track KLT (new
effects -> track same-layer edge).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New crate effectcraft-model (L2): glTF 2.0 (.gltf/.glb, data URIs, external buffers and
images, PBR metallic-roughness with base/MR/normal/occlusion/emissive textures, node
hierarchy, skins, step/linear/cubic animations) and OBJ/MTL import, parametric primitives,
extruded/bevelled outline meshes and polygon triangulation with holes.
Project: FootageKind::Model, LayerSource::Model/Primitive, Layer::environment, Geometry and
Material Options builders, Environment light Source. Media probes and loads models
(FootageSource::model). Engine: layer.newModel, layer.new3dPrimitive/newPrimitive,
comp.renderer, layer.environment, material.set/reset/duplicateAssign/revealSource (stubs
replaced); File > Import and layer.addItem pick up models. Hand-written fixtures with
attribution sidecars.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Auto backend keeps comps with 3D layers on the CPU compositor (3D runs are
still CPU-composited; the GPU round-trip made them slower).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>