summaryrefslogtreecommitdiff
path: root/apps/web/src/services
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-08-02 19:59:32 +0200
committercashmere <cashmere@autistici.org>2026-08-08 10:40:12 +0200
commit237248321a1a40b9b98e7e0a6df156d0aa247ef0 (patch)
tree62f2f46474b08c3b7723e78a2f4dd9cf58d64494 /apps/web/src/services
parent465071d8232e74b1690280a38a86d435269fc35d (diff)
downloadopencut-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.ts16
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,