diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-06 01:23:47 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-06 01:23:47 +0200 |
| commit | fcc09e80e253831a163e2e4941542e0b34f80740 (patch) | |
| tree | 4cc7aafd0756bb3fa23dfd41080237e462b5ecf2 /apps/web/src/lib/animation/curve-bridge.ts | |
| parent | c56d6f8188cc1c0e72d75611269a8bda7b79e727 (diff) | |
| parent | dedb13546a16235e7d6649961d0c9b235f62aa34 (diff) | |
| download | opencut-fcc09e80e253831a163e2e4941542e0b34f80740.tar.gz | |
Merge branch 'temp'
Diffstat (limited to 'apps/web/src/lib/animation/curve-bridge.ts')
| -rw-r--r-- | apps/web/src/lib/animation/curve-bridge.ts | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/apps/web/src/lib/animation/curve-bridge.ts b/apps/web/src/lib/animation/curve-bridge.ts new file mode 100644 index 00000000..55f96933 --- /dev/null +++ b/apps/web/src/lib/animation/curve-bridge.ts @@ -0,0 +1,82 @@ +import { TIME_EPSILON_SECONDS } from "@/constants/animation-constants"; +import { + getDefaultLeftHandle, + getDefaultRightHandle, +} from "@/lib/animation/bezier"; +import type { + CurveHandle, + NormalizedCubicBezier, + ScalarAnimationKey, +} from "@/lib/animation/types"; + +const VALUE_EPSILON = 1e-6; + +function clamp01({ value }: { value: number }): number { + return Math.max(0, Math.min(1, value)); +} + +export function getNormalizedCubicBezierForScalarSegment({ + leftKey, + rightKey, +}: { + leftKey: ScalarAnimationKey; + rightKey: ScalarAnimationKey; +}): NormalizedCubicBezier | null { + const spanTime = rightKey.time - leftKey.time; + const spanValue = rightKey.value - leftKey.value; + if ( + Math.abs(spanTime) <= TIME_EPSILON_SECONDS || + Math.abs(spanValue) <= VALUE_EPSILON + ) { + return null; + } + + const rightHandle = + leftKey.rightHandle ?? getDefaultRightHandle({ leftKey, rightKey }); + const leftHandle = + rightKey.leftHandle ?? getDefaultLeftHandle({ leftKey, rightKey }); + + return [ + clamp01({ value: rightHandle.dt / spanTime }), + rightHandle.dv / spanValue, + clamp01({ value: 1 + leftHandle.dt / spanTime }), + 1 + leftHandle.dv / spanValue, + ]; +} + +export function getCurveHandlesForNormalizedCubicBezier({ + leftKey, + rightKey, + cubicBezier, +}: { + leftKey: ScalarAnimationKey; + rightKey: ScalarAnimationKey; + cubicBezier: NormalizedCubicBezier; +}): { + rightHandle: CurveHandle; + leftHandle: CurveHandle; +} | null { + const spanTime = rightKey.time - leftKey.time; + const spanValue = rightKey.value - leftKey.value; + if ( + Math.abs(spanTime) <= TIME_EPSILON_SECONDS || + Math.abs(spanValue) <= VALUE_EPSILON + ) { + return null; + } + + const [rawX1, y1, rawX2, y2] = cubicBezier; + const x1 = clamp01({ value: rawX1 }); + const x2 = clamp01({ value: rawX2 }); + + return { + rightHandle: { + dt: spanTime * x1, + dv: spanValue * y1, + }, + leftHandle: { + dt: spanTime * (x2 - 1), + dv: spanValue * (y2 - 1), + }, + }; +} |
