diff options
Diffstat (limited to 'apps/web/src/lib/animation')
| -rw-r--r-- | apps/web/src/lib/animation/bezier.ts | 4 | ||||
| -rw-r--r-- | apps/web/src/lib/animation/binding-values.ts | 11 | ||||
| -rw-r--r-- | apps/web/src/lib/animation/interpolation.ts | 9 | ||||
| -rw-r--r-- | apps/web/src/lib/animation/keyframes.ts | 6 | ||||
| -rw-r--r-- | apps/web/src/lib/animation/target-resolver.ts | 18 |
5 files changed, 23 insertions, 25 deletions
diff --git a/apps/web/src/lib/animation/bezier.ts b/apps/web/src/lib/animation/bezier.ts index 4dce027e..5a9758ed 100644 --- a/apps/web/src/lib/animation/bezier.ts +++ b/apps/web/src/lib/animation/bezier.ts @@ -1,5 +1,7 @@ import type { ScalarAnimationKey } from "@/lib/animation/types"; +const BEZIER_SOLVE_ITERATIONS = 20; + export function getBezierPoint({ progress, p0, @@ -68,7 +70,7 @@ export function solveBezierProgressForTime({ const leftHandle = rightKey.leftHandle ?? getDefaultLeftHandle({ leftKey, rightKey }); - for (let iteration = 0; iteration < 20; iteration++) { + for (let iteration = 0; iteration < BEZIER_SOLVE_ITERATIONS; iteration++) { const mid = (lower + upper) / 2; const estimate = getBezierPoint({ progress: mid, diff --git a/apps/web/src/lib/animation/binding-values.ts b/apps/web/src/lib/animation/binding-values.ts index 6f7ce995..344fd776 100644 --- a/apps/web/src/lib/animation/binding-values.ts +++ b/apps/web/src/lib/animation/binding-values.ts @@ -13,6 +13,7 @@ import type { Vector2AnimationBinding, VectorValue, } from "@/lib/animation/types"; +import { clamp } from "@/utils/math"; interface LinearRgba { r: number; @@ -25,10 +26,6 @@ export type AnimationComponentValue = number | DiscreteValue; const toRgb = converter("rgb"); -function clamp01({ value }: { value: number }): number { - return Math.max(0, Math.min(1, value)); -} - function srgbToLinear({ value }: { value: number }): number { return value <= 0.04045 ? value / 12.92 @@ -36,7 +33,7 @@ function srgbToLinear({ value }: { value: number }): number { } function linearToSrgb({ value }: { value: number }): number { - const clamped = clamp01({ value }); + const clamped = clamp({ value, min: 0, max: 1 }); return clamped <= 0.0031308 ? clamped * 12.92 : 1.055 * Math.pow(clamped, 1 / 2.4) - 0.055; @@ -234,7 +231,7 @@ export function parseColorToLinearRgba({ r: srgbToLinear({ value: rgb.r ?? 0 }), g: srgbToLinear({ value: rgb.g ?? 0 }), b: srgbToLinear({ value: rgb.b ?? 0 }), - a: clamp01({ value: rgb.alpha ?? 1 }), + a: clamp({ value: rgb.alpha ?? 1, min: 0, max: 1 }), }; } @@ -248,7 +245,7 @@ export function formatLinearRgba({ r: linearToSrgb({ value: color.r }), g: linearToSrgb({ value: color.g }), b: linearToSrgb({ value: color.b }), - alpha: clamp01({ value: color.a }), + alpha: clamp({ value: color.a, min: 0, max: 1 }), } as const; return rgb.alpha < 1 ? formatHex8(rgb) : formatHex(rgb); } diff --git a/apps/web/src/lib/animation/interpolation.ts b/apps/web/src/lib/animation/interpolation.ts index 9609441c..67456aa0 100644 --- a/apps/web/src/lib/animation/interpolation.ts +++ b/apps/web/src/lib/animation/interpolation.ts @@ -9,6 +9,7 @@ import type { ScalarSegmentType, } from "@/lib/animation/types"; import { TIME_EPSILON_SECONDS } from "@/constants/animation-constants"; +import { clamp } from "@/utils/math"; import { getBezierPoint, getDefaultLeftHandle, @@ -41,10 +42,6 @@ function isWithinTimePair({ ); } -function clamp01({ value }: { value: number }): number { - return Math.max(0, Math.min(1, value)); -} - function lerpNumber({ leftValue, rightValue, @@ -287,8 +284,10 @@ export function getScalarChannelValueAtTime({ return rightKey.value; } - const progress = clamp01({ + const progress = clamp({ value: (time - leftKey.time) / span, + min: 0, + max: 1, }); if (leftKey.segmentToNext === "linear") { return lerpNumber({ diff --git a/apps/web/src/lib/animation/keyframes.ts b/apps/web/src/lib/animation/keyframes.ts index 7eaa5ed6..d72f9e16 100644 --- a/apps/web/src/lib/animation/keyframes.ts +++ b/apps/web/src/lib/animation/keyframes.ts @@ -440,9 +440,9 @@ export function upsertPathKeyframe({ keyframeId?: string; kind: AnimationBindingKind; defaultInterpolation: AnimationInterpolation; - coerceValue: (value: AnimationValue) => AnimationValue | null; + coerceValue: ({ value }: { value: AnimationValue }) => AnimationValue | null; }): ElementAnimations | undefined { - const coercedValue = coerceValue(value); + const coercedValue = coerceValue({ value }); if (coercedValue === null) { return animations; } @@ -547,7 +547,7 @@ export function upsertElementKeyframe({ keyframeId, kind: propertyDefinition.kind, defaultInterpolation: propertyDefinition.defaultInterpolation, - coerceValue: (nextValue) => + coerceValue: ({ value: nextValue }) => coerceAnimationValueForProperty({ propertyPath, value: nextValue, diff --git a/apps/web/src/lib/animation/target-resolver.ts b/apps/web/src/lib/animation/target-resolver.ts index 06c9e140..64bb8709 100644 --- a/apps/web/src/lib/animation/target-resolver.ts +++ b/apps/web/src/lib/animation/target-resolver.ts @@ -32,9 +32,9 @@ export interface AnimationPathDescriptor { kind: AnimationBindingKind; defaultInterpolation: AnimationInterpolation; numericRanges?: Partial<Record<string, NumericSpec>>; - coerceValue(value: AnimationValue): AnimationValue | null; - getBaseValue(): AnimationValue | null; - setBaseValue(value: AnimationValue): TimelineElement; + coerceValue: ({ value }: { value: AnimationValue }) => AnimationValue | null; + getBaseValue: () => AnimationValue | null; + setBaseValue: ({ value }: { value: AnimationValue }) => TimelineElement; } export function getParamValueKind({ @@ -135,9 +135,9 @@ function buildGraphicParamDescriptor({ kind: getParamValueKind({ param }), defaultInterpolation: getParamDefaultInterpolation({ param }), numericRanges: getParamNumericRange({ param }), - coerceValue: (value) => coerceAnimationValueForParam({ param, value }), + coerceValue: ({ value }) => coerceAnimationValueForParam({ param, value }), getBaseValue: () => element.params[param.key] ?? param.default, - setBaseValue: (value) => { + setBaseValue: ({ value }) => { const coercedValue = coerceAnimationValueForParam({ param, value }); if (coercedValue === null) { return element; @@ -183,9 +183,9 @@ function buildEffectParamDescriptor({ kind: getParamValueKind({ param }), defaultInterpolation: getParamDefaultInterpolation({ param }), numericRanges: getParamNumericRange({ param }), - coerceValue: (value) => coerceAnimationValueForParam({ param, value }), + coerceValue: ({ value }) => coerceAnimationValueForParam({ param, value }), getBaseValue: () => effect.params[param.key] ?? param.default, - setBaseValue: (value) => { + setBaseValue: ({ value }) => { const coercedValue = coerceAnimationValueForParam({ param, value }); if (coercedValue === null) { return element; @@ -239,7 +239,7 @@ export function resolveAnimationTarget({ kind: propertyDefinition.kind, defaultInterpolation: propertyDefinition.defaultInterpolation, numericRanges: propertyDefinition.numericRanges, - coerceValue: (value) => + coerceValue: ({ value }) => coerceAnimationValueForProperty({ propertyPath: path, value, @@ -249,7 +249,7 @@ export function resolveAnimationTarget({ element, propertyPath: path, }), - setBaseValue: (value) => { + setBaseValue: ({ value }) => { const coercedValue = propertyDefinition.coerceValue({ value }); if (coercedValue === null) { return element; |
