summaryrefslogtreecommitdiff
path: root/apps/web/src/masks/components
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-29 18:41:15 +0200
committerMaze Winther <mazewinther@gmail.com>2026-05-02 03:27:23 +0200
commit79dcec8a2ec2f5cad9be95e5b52fbfa752fb6ac4 (patch)
tree99ff9393c4a550669ebac921c6a0535437a39413 /apps/web/src/masks/components
parent97f8d1968f186028e41f83b04c0897130e6c69f4 (diff)
downloadopencut-79dcec8a2ec2f5cad9be95e5b52fbfa752fb6ac4.tar.gz
refactor: split builtin and freeform masks
Made-with: Cursor
Diffstat (limited to 'apps/web/src/masks/components')
-rw-r--r--apps/web/src/masks/components/masks-tab.tsx53
1 files changed, 41 insertions, 12 deletions
diff --git a/apps/web/src/masks/components/masks-tab.tsx b/apps/web/src/masks/components/masks-tab.tsx
index 97fba3ab..d6729d6d 100644
--- a/apps/web/src/masks/components/masks-tab.tsx
+++ b/apps/web/src/masks/components/masks-tab.tsx
@@ -3,7 +3,11 @@
import type { MaskableElement } from "@/timeline";
import type { Mask, MaskType, TextMask } from "@/masks/types";
import type { NumberParamDefinition, SelectParamDefinition } from "@/params";
-import { masksRegistry, buildDefaultMaskInstance } from "@/masks";
+import {
+ buildDefaultMaskInstance,
+ getMaskDefinition,
+ getMaskDefinitionsForMenu,
+} from "@/masks";
import { useEditor } from "@/editor/use-editor";
import { useElementPreview } from "@/timeline/hooks/use-element-preview";
import { useMenuPreview } from "@/editor/use-menu-preview";
@@ -85,12 +89,43 @@ type PreviewParamHandler = (
key: string,
) => (value: number | string | boolean) => void;
-type RegisteredMaskDefinition = ReturnType<(typeof masksRegistry)["get"]>;
+type RegisteredMaskDefinition = ReturnType<typeof getMaskDefinition>;
function isTextMask(mask: Mask): mask is TextMask {
return mask.type === "text";
}
+function withPreviewedMaskParam({
+ mask,
+ key,
+ value,
+}: {
+ mask: Mask;
+ key: string;
+ value: number | string | boolean;
+}): Mask {
+ switch (mask.type) {
+ case "split":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ case "cinematic-bars":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ case "rectangle":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ case "ellipse":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ case "heart":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ case "diamond":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ case "star":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ case "text":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ case "freeform":
+ return { ...mask, params: { ...mask.params, [key]: value } };
+ }
+}
+
export function MasksTab({ element, trackId }: MasksTabProps) {
const editor = useEditor();
const { renderElement, previewUpdates, commit } =
@@ -99,7 +134,7 @@ export function MasksTab({ element, trackId }: MasksTabProps) {
elementId: element.id,
fallback: element,
});
- const maskDefs = masksRegistry.getAll();
+ const maskDefs = getMaskDefinitionsForMenu();
const tracks = useEditor(
(e) => e.timeline.getPreviewTracks() ?? e.scenes.getActiveScene().tracks,
);
@@ -210,16 +245,10 @@ export function MasksTab({ element, trackId }: MasksTabProps) {
const updatedMasks = renderMasks.map((existingMask, maskIndex) =>
maskIndex !== index
? existingMask
- : {
- ...existingMask,
- params: {
- ...existingMask.params,
- [key]: value,
- },
- },
+ : withPreviewedMaskParam({ mask: existingMask, key, value }),
);
- previewUpdates({ masks: updatedMasks } as Partial<MaskableElement>);
+ previewUpdates({ masks: updatedMasks });
};
return (
@@ -301,7 +330,7 @@ function MaskItem({
onCommit,
}: MaskItemProps) {
const editor = useEditor();
- const definition = masksRegistry.get(mask.type);
+ const definition = getMaskDefinition(mask.type);
return (
<Section sectionKey={`mask-item:${mask.id}`} showTopBorder={false}>