summaryrefslogtreecommitdiff
path: root/apps/web/src/components/editor/panels/properties/hooks/use-keyframed-number-property.ts
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-03-25 16:47:22 +0100
committerMaze Winther <mazewinther@gmail.com>2026-03-29 15:48:22 +0200
commit8db3bead13441a5882d8689dfc6a9f09c82375d9 (patch)
treee9d0cafa93904ffcbec3188c37961bcc16c6422d /apps/web/src/components/editor/panels/properties/hooks/use-keyframed-number-property.ts
parent39ea298a9ccba3104c549c0ca079c231981811f5 (diff)
downloadopencut-8db3bead13441a5882d8689dfc6a9f09c82375d9.tar.gz
feat: masks, properties refactor, shaders, storage migrations, and more
Diffstat (limited to 'apps/web/src/components/editor/panels/properties/hooks/use-keyframed-number-property.ts')
-rw-r--r--apps/web/src/components/editor/panels/properties/hooks/use-keyframed-number-property.ts26
1 files changed, 18 insertions, 8 deletions
diff --git a/apps/web/src/components/editor/panels/properties/hooks/use-keyframed-number-property.ts b/apps/web/src/components/editor/panels/properties/hooks/use-keyframed-number-property.ts
index 11aa049c..0f0168f8 100644
--- a/apps/web/src/components/editor/panels/properties/hooks/use-keyframed-number-property.ts
+++ b/apps/web/src/components/editor/panels/properties/hooks/use-keyframed-number-property.ts
@@ -4,8 +4,9 @@ import {
hasKeyframesForPath,
upsertElementKeyframe,
} from "@/lib/animation";
-import type { AnimationPropertyPath, ElementAnimations } from "@/types/animation";
-import type { TimelineElement } from "@/types/timeline";
+import type { AnimationPropertyPath, ElementAnimations } from "@/lib/animation/types";
+import type { TimelineElement } from "@/lib/timeline";
+import { snapToStep } from "@/utils/math";
import { usePropertyDraft } from "./use-property-draft";
export function useKeyframedNumberProperty({
@@ -18,6 +19,7 @@ export function useKeyframedNumberProperty({
displayValue,
parse,
valueAtPlayhead,
+ step,
buildBaseUpdates,
}: {
trackId: string;
@@ -29,9 +31,12 @@ export function useKeyframedNumberProperty({
displayValue: string;
parse: (input: string) => number | null;
valueAtPlayhead: number;
+ step?: number;
buildBaseUpdates: ({ value }: { value: number }) => Partial<TimelineElement>;
}) {
const editor = useEditor();
+ const snapValue = (value: number) =>
+ step != null ? snapToStep({ value, step }) : value;
const hasAnimatedKeyframes = hasKeyframesForPath({ animations, propertyPath });
const keyframeAtTime = isPlayheadWithinElementRange
@@ -43,6 +48,7 @@ export function useKeyframedNumberProperty({
hasAnimatedKeyframes && isPlayheadWithinElementRange;
const previewValue = ({ value }: { value: number }) => {
+ const nextValue = snapValue(value);
if (shouldUseAnimatedChannel) {
editor.timeline.previewElements({
updates: [
@@ -54,7 +60,7 @@ export function useKeyframedNumberProperty({
animations,
propertyPath,
time: localTime,
- value,
+ value: nextValue,
}),
},
},
@@ -68,7 +74,7 @@ export function useKeyframedNumberProperty({
{
trackId,
elementId,
- updates: buildBaseUpdates({ value }),
+ updates: buildBaseUpdates({ value: nextValue }),
},
],
});
@@ -76,7 +82,10 @@ export function useKeyframedNumberProperty({
const propertyDraft = usePropertyDraft({
displayValue,
- parse,
+ parse: (input) => {
+ const parsedValue = parse(input);
+ return parsedValue === null ? null : snapValue(parsedValue);
+ },
onPreview: (value) => previewValue({ value }),
onCommit: () => editor.timeline.commitPreview(),
});
@@ -107,13 +116,14 @@ export function useKeyframedNumberProperty({
elementId,
propertyPath,
time: localTime,
- value: valueAtPlayhead,
+ value: snapValue(valueAtPlayhead),
},
],
});
};
const commitValue = ({ value }: { value: number }) => {
+ const nextValue = snapValue(value);
if (shouldUseAnimatedChannel) {
editor.timeline.upsertKeyframes({
keyframes: [
@@ -122,7 +132,7 @@ export function useKeyframedNumberProperty({
elementId,
propertyPath,
time: localTime,
- value,
+ value: nextValue,
},
],
});
@@ -134,7 +144,7 @@ export function useKeyframedNumberProperty({
{
trackId,
elementId,
- updates: buildBaseUpdates({ value }),
+ updates: buildBaseUpdates({ value: nextValue }),
},
],
});