diff options
| author | cashmere <cashmere@autistici.org> | 2026-08-02 19:59:32 +0200 |
|---|---|---|
| committer | cashmere <cashmere@autistici.org> | 2026-08-08 10:40:12 +0200 |
| commit | 237248321a1a40b9b98e7e0a6df156d0aa247ef0 (patch) | |
| tree | 62f2f46474b08c3b7723e78a2f4dd9cf58d64494 /apps/web/src/services | |
| parent | 465071d8232e74b1690280a38a86d435269fc35d (diff) | |
| download | opencut-237248321a1a40b9b98e7e0a6df156d0aa247ef0.tar.gz | |
feat: pan & zoom motion presets
Ken Burns-style motion effects (zoom in/out, pan left/right/up/down) that
drag onto clips like regular effects. Instead of shader passes they
evaluate a per-frame transform offset in resolveVisualState, so they
stack with keyframed transforms and work in preview and export.
- intensity param (0-100%, keyframable) scales the whole effect
- easing select maps progress through the graph editor's bezier presets
- supportsStandalone: false hides them from effect-track creation
- empty shader pass groups are filtered out so pass-less effects and
zero-intensity blur no longer crash the compositor
Diffstat (limited to 'apps/web/src/services')
| -rw-r--r-- | apps/web/src/services/renderer/resolve.ts | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/apps/web/src/services/renderer/resolve.ts b/apps/web/src/services/renderer/resolve.ts index 5335de2d..a4c8d303 100644 --- a/apps/web/src/services/renderer/resolve.ts +++ b/apps/web/src/services/renderer/resolve.ts @@ -6,6 +6,7 @@ import { intensityToSigma, } from "@/effects/definitions/blur"; import { effectsRegistry, resolveEffectPasses } from "@/effects"; +import { applyMotionEffects } from "@/effects/motion"; import type { Effect, EffectPass } from "@/effects/types"; import { getSourceTimeAtClipTime } from "@/retime"; import { @@ -125,7 +126,8 @@ function resolveEffectPassGroups({ width, height, }); - }); + }) + .filter((passes) => passes.length > 0); } function resolveVisualState({ @@ -149,10 +151,18 @@ function resolveVisualState({ elementStartTime: params.timeOffset, elementDuration: params.duration, }); - const transform = resolveTransformAtTime({ - baseTransform: params.transform, + const transform = applyMotionEffects({ + baseTransform: resolveTransformAtTime({ + baseTransform: params.transform, + animations: params.animations, + localTime, + }), + effects: params.effects, animations: params.animations, localTime, + duration: params.duration, + canvasWidth: context.renderer.width, + canvasHeight: context.renderer.height, }); const opacity = resolveOpacityAtTime({ baseOpacity: params.opacity, |
