Commit Graph
107 Commits
Author SHA1 Message Date
bflatastic 03bae81edd Merge remote-tracking branch 'origin/main' into HEAD 2026-10-30 07:04:56 +07:00
bflatastic 6c9e625a2e Merge remote-tracking branch 'origin/main' into HEAD 2026-10-30 07:04:33 +07:00
bflatasticandClaude Opus 5.5 883171eece Scripts: FootageItem.replace() swaps in one file, as in After Effects
Since #2107, Replace Footage keeps an item's kind by default, so
replace() on a sequence item brought the new file's whole numbered run.
In After Effects, replace() swaps in the one file and replaceWithSequence()
brings a run; replace() now asks for exactly that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 05:59:40 +07:00
bflatastic bd34ab21b6 Merge main into #2279; keep main's Scripts subfolders (RESERVED_FOLDERS) next to the Startup/Shutdown constants, merge docs rows 2026-10-30 05:34:26 +07:00
bflatastic e28b43dc40 Merge main into #2355; ROADMAP progress log keeps both entries 2026-10-30 05:30:25 +07:00
Claude 942b478472 1063: name the companion properties of text animators (Track Type, Skew Axis, X / Y Rotation)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDvxCS8xcR28VArjzn1x7U
2026-10-29 11:22:49 +00:00
Claude 55761e226f Merge main into fix/1063-text-animator-stacked
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDvxCS8xcR28VArjzn1x7U
2026-10-29 09:27:06 +00:00
dotCooCoo 3f85aa111e Scripts: move the Startup and Shutdown script tests into tests/startup.rs
The tests now sit with the crate's other test modules under crates/script/src/tests/ and are declared in tests.rs. docs/scripting-parity.md points at the new path.
2026-10-29 01:36:02 -07:00
dotCooCoo 32f058ea05 Merge main into feat/wiggle-paths-spatial-phase 2026-10-28 05:39:33 -07:00
Dylan M. Taylor 1d2c0d4248 Refactor script for strict Clippy checks 2026-10-28 06:09:21 +00:00
dotCooCoo bb4f976384 Merge main and retain the Wiggle Transform command schema 2026-10-27 11:41:42 -07:00
aiongg b7b75ed37a style: cargo fmt on the moved files 2026-10-26 21:54:30 +00:00
aiongg 48253ff5e1 refactor(script): move loose test files to src/tests/ 2026-10-26 21:49:11 +00:00
dotCooCoo 8ebacda419 Shapes: Wiggle Paths has Spatial Phase, which slides its wiggle along the path
Wiggle Paths had Size, Detail, Points, Wiggles/Second, Correlation,
Temporal Phase and Random Seed, but no Spatial Phase, which After
Effects lists among its properties (ADBE Vector Spatial Phase). Spatial
Phase now moves each point's own displacement along its subpath: 360
degrees is once around, and a fraction of a point is interpolated
between neighbors. At 0 degrees a path draws as before.

A project saved without the property gets it at 0 degrees, after
Temporal Phase, when it opens. Scripts can read and set every Wiggle
Paths property by its match name.
2026-10-25 16:06:28 -07:00
dotCooCoo 62cd2364d5 Shapes: add the Wiggle Transform path operation, which wiggles paths and each Repeater copy
A shape layer's Contents > Add menu had every After Effects path operation
except Wiggle Transform. It is now a shape item (layer.addShapeItem kind
wiggler, "ADBE Vector Filter - Wiggler" for scripts) with Wiggles/Second,
Correlation, Temporal Phase, Spatial Phase, Random Seed and a Transform
group whose Anchor Point, Position, Scale and Rotation set how far each
transformation wiggles.

The values come from the Wiggly selector's noise, with each Repeater copy
as one unit: the copies of a Repeater above the operation, in its group or
a nested one, wiggle independently as far as Correlation allows, and the
copies of a Repeater below it wiggle the same way. A paint above it whose
paths all move by one matrix moves its gradient and stroke scale with them.
The layer cache keys a layer with a Wiggle Transform by time.
2026-10-24 18:11:29 -07:00
aiongg a9d5ea90a8 Merge #1958: script: comp.width and comp.height resize the frame without moving the layers (#1942) (@Anubhav-Rai) 2026-10-24 01:12:08 +00:00
aiongg d664e403ae Merge #2185: Project Settings: Frame Count, Start at 0 or Start at 1 (@marcoarnulfo) 2026-10-24 00:13:55 +00:00
aiongg ce73d42c42 Merge #1929: Layer: replace a layer's source with Alt-drag and Ctrl+Alt+/ (#991) (@ki2pixel) 2026-10-23 21:26:51 +00:00
Marco Arnulfo 952b04322e Project Settings: Frame Count, Start at 0 or Start at 1 (part of #1807)
file.projectSettings takes frameStart (0|1), the Project Settings dialog shows Frame Count, and scripts get app.project.framesCountType and displayStartFrame. The setting was already read by the Frames and Feet + Frames time display; nothing could change it.
2026-10-23 03:07:01 +02:00
Anubhav-RaiandClaude Opus 5 88045641f3 script: comp.width and comp.height resize the frame without moving the layers (#1942)
The setters go through `comp.settings`, which defaults to the Composition Settings dialog's
centre anchor, so `comp.width = 800` on a 400-wide comp shifted every unparented layer — and
all of its position keys — by 200 px. A script that resized a precomp then found its pixel
coordinates had moved under it.

After Effects' width and height setters only change the frame; moving the contents is what
"resize from centre" scripts do for themselves. The setters now pass `anchor: 0` (top left).
The dialog, which is where the anchor belongs, is untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-23 02:48:28 +05:30
Anubhav-RaiandClaude Opus 5 a67ca11d1c script: setValue rejects an array of the wrong dimension (#1936)
A 2-D point property took any array: `[1, 2, 3]` and `[1, 2, 3, 4]` were cut to `[1, 2]` and
`[1]` was broadcast to `[1, 1]`, each reported as success, so a script holding a wrong value
silently did something else instead of failing. After Effects raises "Array is not of the
correct dimension" and leaves the property unchanged.

The length must now match the property's dimension, with the one exception After Effects also
makes: two values for a 3-D property, where z stays 0, so `position.setValue([x, y])` keeps
working.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-20 20:23:41 +05:30
Camille Moine 8d887fd6da Layer: replace a layer's source with Alt-drag and Ctrl+Alt+/ (#991, #813)
Alt/Option-drag a Project item onto a Timeline layer, or press Ctrl+Alt+/ (Cmd+Opt+/) with layers and an item selected, to swap the layer's source. The layer keeps its name, timing, transforms, keyframes, expressions, effects, masks, switches, parenting and track matte; a source with audio adds Audio properties when missing. Precompositions can't be nested inside themselves.

AVLayer.replaceSource now runs the same engine command and closes the replaceSource part of #813.
2026-10-20 12:18:46 +02:00
Brandon Thomas 30efc87a2a Merge pull request #1694 2026-10-18 09:35:34 -04:00
Brandon Thomas 12d8e13bae Merge pull request #1406 2026-10-18 09:35:33 -04:00
Kristian Myram 114d8709a1 1063: use canonical text animator match names and resolve main 2026-10-17 20:50:55 +00:00
Ayberk A. ab8af6ae95 test(script): per-key methods in another comp leave both key selections alone (#1531)
The worse half of #1531: when the property's comp remembers a key the user
selected, the old code didn't just do nothing, it eased, held or removed
that selected key instead of the one named. This test, written by
@switch87 in #1558, pins it: only the named keys change, removeKey(1)
removes key 1, the active comp stays active with its own key selection,
and the other comp's remembered selection comes back as it was. It fails
on the code before #1558 and passes on main.
2026-10-17 00:13:27 +03:00
BFlat 8e96fdd0fc Merge pull request #1351 from DWAA1660/fix/1246-script-confirmed-flag
Scripts: a script can't confirm executing a file for itself (#1246)
2026-10-16 19:01:15 +07:00
BFlat 5c02fe902f Merge pull request #1558 from AyberkA0/script-keys-closed-comp
fix(script): per-key methods act on keys outside the active comp (#1531)
2026-10-16 19:00:16 +07:00
BFlat c133e09e37 Merge pull request #1371 from marcoarnulfo/fix/layer-property-shortcuts
Scripting: test that Layer.property() resolves AE's top-level shortcuts
2026-10-16 18:09:39 +07:00
Ayberk A. 9635321f1a fix(script): per-key methods act on keys outside the active comp (#1531)
`exec_on_keys` put the named keys in the key selection, then `exec` made
the keys' comp active. Since comps keep their own selections (#1037),
activating the comp stored the injected keys with the comp that had been
active and brought back the target comp's own key selection, usually
empty, so `keys.interpolation` and `keys.velocity` had nothing to act on:
setInterpolationTypeAtKey and setTemporalEaseAtKey were silently ignored
in any comp other than the active one. The keys' comp is now made active
before the keys are selected, and the comp that was active comes back
afterwards, as `exec` does for its own target (now `leave_comp`).
2026-10-15 14:42:50 +03:00
Marco Arnulfo 1b44c5c98a Scripting: Stroke and Hue/Saturation parameters use After Effects' match-name numbers (part of #1405) 2026-10-14 09:15:12 +02:00
Marco Arnulfo dd5afffee3 Scripting: test that Layer.property() resolves AE's top-level shortcuts (#1348) 2026-10-14 00:55:12 +02:00
DWAA1660andClaude Opus 5.5 7a9ca5810a Scripts: a script can't confirm executing a file for itself (#1246)
With Warn User When Executing Files on, file.executeFile asks the
frontend first, and the frontend's answer re-runs it with
`confirmed: true`. That flag was taken from the parameters whoever
called, so a script could pass it itself (app.run('file.executeFile',
{path, confirmed: true}), also inside engine.batch) and the file opened
without the question, as long as the user had allowed file and network
access.

`confirmed` now counts only when the command isn't running for a script
(Session::running_for_script, which #590 uses for the same reason and
which stays set through nested batches). A script's request always gets
the question; the user's answer from the frontend's form still opens
the file; with the warning off nothing changes. The permission gate
itself is unchanged.

Tests: engine a_script_cannot_confirm_executing_a_file_for_itself
(execute_for_script directly and through engine.batch; the frontend's
confirmation; warning off) and the same through real JavaScript in the
script crate (app.run, app.run('engine.batch'), File.execute()). Both
fail on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:47:51 -06:00
Kristian MyramandClaude Haiku 5.5 fdc515f5be #1063: find an undefined name's first use from the failing frame on
A ReferenceError's first use was searched across the whole file, so a mention
earlier in a comment, a string or another function could report the wrong line.
The search now starts at the innermost script frame's line, and covers the whole
file only when there is no frame. Follow-up to storytold/effectcraft#1161.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-13 21:58:52 +02:00
Kristian MyramandClaude Sonnet 5.5 dd36eed8e9 Merge upstream main into fix/1063-text-animator-stacked
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-13 21:56:33 +02:00
Brandon Thomas bb4972a886 Merge pull request #1160 from nanox333/fix/1063-levels-alpha-name
# Conflicts:
#	crates/script/src/tests.rs
2026-10-13 04:35:20 -04:00
Brandon Thomas 286a521598 Merge pull request #1037 from vbasky/fix/1001-selection-persist
# Conflicts:
#	crates/engine/src/lib.rs
2026-10-13 04:34:34 -04:00
Brandon Thomas 6ffb2823c7 Merge pull request #1188 from redonion23/fix/816-save-frame-to-png 2026-10-13 04:29:17 -04:00
Brandon Thomas fa5ce34012 Merge pull request #1119 from marcoarnulfo/fix/ges-jsx-keyframes
# Conflicts:
#	crates/script/src/tests.rs
2026-10-13 04:29:06 -04:00
Brandon Thomas 0e4f3bfb8f Merge pull request #1043 from vbasky/fix/1000-sampleimage-footage
# Conflicts:
#	crates/script/src/tests.rs
2026-10-13 04:28:50 -04:00
Brandon Thomas ee682bbfd9 Merge pull request #1172 from redonion23/fix/815-stroke-dash-matchnames
# Conflicts:
#	crates/script/src/tests.rs
2026-10-13 04:28:45 -04:00
Brandon Thomas 092834b703 Merge pull request #1156 from redonion23/fix/814-removekey-linear 2026-10-13 04:28:44 -04:00
Brandon Thomas a55155bd7d Merge pull request #1191 from redonion23/fix/813-footage-proxy-scripting 2026-10-13 04:28:34 -04:00
Brandon Thomas 66be8857b5 Merge pull request #1162 from nanox333/fix/1063-light-casts-shadows
# Conflicts:
#	crates/script/src/tests.rs
2026-10-13 04:28:33 -04:00
Brandon Thomas 5c0ac48f31 Merge pull request #1123 from nanox333/fix/808-source-point-convert
# Conflicts:
#	crates/script/src/tests.rs
2026-10-13 04:28:30 -04:00
Brandon Thomas 39ef24af3a Merge pull request #1093 from moecr7/codex/fix-1063-text-line-breaks 2026-10-13 04:28:28 -04:00
Brandon Thomas b77018ea8f Merge pull request #1161 from nanox333/fix/1063-undefined-name-location 2026-10-13 04:27:32 -04:00
Vikram Bhaskaran c46f80faa2 Store each comp's layer selection on its own.
A single selected_layers list kept ids from every comp, so the active comp looked selected whenever another comp was. Opening a comp and running a script against a different comp now park and restore that selection.
2026-10-13 17:46:02 +11:00
Vikram Bhaskaran 8c986a1bec Keep closed comps' layer selections across scripts (#1001)
sanitize_state dropped every selected layer not in the active comp at the
end of each script run, so a layer selected by script in a comp that was not
open was gone by the next script call. Every comp keeps its own selection as
in After Effects; only ids gone from every comp are dropped now. UI and
engine lookups resolve selections per comp and tolerate foreign ids.
2026-10-13 17:39:16 +11:00
redonion23andClaude Opus 5.5 004984d853 Scripting: footage proxies, replaceWithSequence and mainSource.conformFrameRate (#813)
FootageItem had no replaceWithSequence, setProxy, setProxyWithSequence or
setProxyToNone, useProxy and proxySource were fixed stubs, and mainSource
was a new object on every read with no conformFrameRate. They now run the
existing commands (file.replaceFootage, file.setProxy, file.useProxy,
file.setProxyNone, file.interpretFootage); the item info reports the proxy
and the conform/native frame rates, and mainSource is one live
FootageSource per FootageItem. replaceSource is not covered: it needs an
engine command that changes a layer's source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 05:59:10 +02:00