diff options
| author | Maze <167211895+mazeincoding@users.noreply.github.com> | 2026-02-23 03:24:02 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-23 03:24:02 +0100 |
| commit | 93d1e3383ce47e45157d70f9ba6251239dae6bc2 (patch) | |
| tree | 1e33a2d7533b65f0e7c8927f03905a1a99937bd1 /apps/web/src/constants | |
| parent | fca99d6126c31fbb18ed9f1034cee6f940b040e8 (diff) | |
| download | opencut-93d1e3383ce47e45157d70f9ba6251239dae6bc2.tar.gz | |
feat: major editor overhaul (assets, properties, timeline, fonts) (#709)
* feat: major editor overhaul (assets, properties, timeline, fonts)
Refactor editor core systems to standardize UI architecture and improve performance.
Assets & Properties:
- Replace monolithic property items with composable `Section` architecture.
- Add specialized sections for Transform, Blending, and Text.
- Implement `NumberField` with scrubbing and math evaluation.
- Add new ColorPicker with EyeDropper and multiple format support.
- Standardize asset panels using new `PanelView` layout.
Fonts & Stickers:
- Implement custom font atlas/sprite system for high-performance previews.
- Add virtualized FontPicker with search and favorites.
- Refactor stickers to use a provider-based architecture (icons, emoji, flags, shapes).
- Standardize sticker IDs to `provider:value` format.
Timeline & Interaction:
- Convert bookmarks to rich objects with notes, colors, and duration.
- Refactor drag-and-drop to use Command pattern (enabling proper undo/redo).
- Add Shift modifier to disable snapping during moves/resizes.
- Add new overlays for layout guides and text editing.
Renderer:
- Add support for multi-line text, custom line-height, and letter-spacing.
- Implement global composite operation (blend modes).
- Update sticker node to resolve dynamic provider IDs.
Infrastructure:
- Add storage migrations (v3->v6) for text weights, sticker IDs, and bookmarks.
- Update global styles and core UI components (Button, Input, Popover).
* add ts-nocheck directive to settings-legacy.tsx to suppress TypeScript errors
* fix: correct global composite operation assignment in TextNode to ensure proper blend mode handling
* deleted shadcn components with errors
* formatting
* fix linter issues
* migrate from next middleware to proxy
* add missing component back
* add breadcrumb back
* chore: add @radix-ui/react-primitive deps
* chore: more deps
* chore: add missing env vars to bun-ci
* next env
Diffstat (limited to 'apps/web/src/constants')
| -rw-r--r-- | apps/web/src/constants/editor-constants.ts | 6 | ||||
| -rw-r--r-- | apps/web/src/constants/font-constants.ts | 88 | ||||
| -rw-r--r-- | apps/web/src/constants/site-constants.ts | 2 | ||||
| -rw-r--r-- | apps/web/src/constants/sticker-constants.ts | 8 | ||||
| -rw-r--r-- | apps/web/src/constants/stickers-constants.ts | 16 | ||||
| -rw-r--r-- | apps/web/src/constants/text-constants.ts | 78 | ||||
| -rw-r--r-- | apps/web/src/constants/timeline-constants.tsx | 15 |
7 files changed, 74 insertions, 139 deletions
diff --git a/apps/web/src/constants/editor-constants.ts b/apps/web/src/constants/editor-constants.ts index 213ea875..00e8f19b 100644 --- a/apps/web/src/constants/editor-constants.ts +++ b/apps/web/src/constants/editor-constants.ts @@ -1,9 +1,3 @@ -import type { TPlatformLayout } from "@/types/editor"; - -export const PLATFORM_LAYOUTS: Record<TPlatformLayout, string> = { - tiktok: "TikTok", -}; - export const PANEL_CONFIG = { panels: { tools: 25, diff --git a/apps/web/src/constants/font-constants.ts b/apps/web/src/constants/font-constants.ts index 46f84848..d115d09b 100644 --- a/apps/web/src/constants/font-constants.ts +++ b/apps/web/src/constants/font-constants.ts @@ -1,79 +1,13 @@ -export interface FontOption { - value: string; - label: string; - category: "system" | "google" | "custom"; - weights?: number[]; - hasClassName?: boolean; -} - -export const FONT_OPTIONS: FontOption[] = [ - // System fonts (always available) - { value: "Arial", label: "Arial", category: "system", hasClassName: false }, - { - value: "Helvetica", - label: "Helvetica", - category: "system", - hasClassName: false, - }, - { - value: "Times New Roman", - label: "Times New Roman", - category: "system", - hasClassName: false, - }, - { - value: "Georgia", - label: "Georgia", - category: "system", - hasClassName: false, - }, - - // Google Fonts (loaded in layout.tsx) - { - value: "Inter", - label: "Inter", - category: "google", - weights: [400, 700], - hasClassName: true, - }, - { - value: "Roboto", - label: "Roboto", - category: "google", - weights: [400, 700], - hasClassName: true, - }, - { - value: "Open Sans", - label: "Open Sans", - category: "google", - hasClassName: true, - }, - { - value: "Playfair Display", - label: "Playfair Display", - category: "google", - hasClassName: true, - }, - { - value: "Comic Neue", - label: "Comic Neue", - category: "google", - hasClassName: false, - }, -] as const; - export const DEFAULT_FONT = "Arial"; -// Type-safe font family union -export type FontFamily = (typeof FONT_OPTIONS)[number]["value"]; - -// Helper functions -export const getFontByValue = (value: string): FontOption | undefined => - FONT_OPTIONS.find((font) => font.value === value); - -export const getGoogleFonts = (): FontOption[] => - FONT_OPTIONS.filter((font) => font.category === "google"); - -export const getSystemFonts = (): FontOption[] => - FONT_OPTIONS.filter((font) => font.category === "system"); +export const SYSTEM_FONTS = new Set([ + "Arial", + "Helvetica", + "Times New Roman", + "Courier New", + "Verdana", + "Georgia", + "monospace", + "sans-serif", + "serif", +]); diff --git a/apps/web/src/constants/site-constants.ts b/apps/web/src/constants/site-constants.ts index ac6cd2cd..10981727 100644 --- a/apps/web/src/constants/site-constants.ts +++ b/apps/web/src/constants/site-constants.ts @@ -1,4 +1,4 @@ -import { OcDataBuddyIcon, OcMarbleIcon, } from "@opencut/ui/icons"; +import { OcDataBuddyIcon, OcMarbleIcon } from "@opencut/ui/icons"; export const SITE_URL = "https://opencut.app"; diff --git a/apps/web/src/constants/sticker-constants.ts b/apps/web/src/constants/sticker-constants.ts new file mode 100644 index 00000000..506e552d --- /dev/null +++ b/apps/web/src/constants/sticker-constants.ts @@ -0,0 +1,8 @@ +export const STICKER_CATEGORIES = { + all: "All", + logos: "Logos", + icons: "Icons", + emoji: "Emoji", + flags: "Flags", + shapes: "Shapes", +}; diff --git a/apps/web/src/constants/stickers-constants.ts b/apps/web/src/constants/stickers-constants.ts deleted file mode 100644 index 3c98d4f7..00000000 --- a/apps/web/src/constants/stickers-constants.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const STICKER_CATEGORIES = [ - "all", - "general", - "brands", - "emoji", -] as const; - -export const STICKER_CATEGORY_CONFIG: Record< - (typeof STICKER_CATEGORIES)[number], - string | undefined -> = { - all: undefined, - general: "General", - brands: "Brands / Social", - emoji: "Emoji", -}; diff --git a/apps/web/src/constants/text-constants.ts b/apps/web/src/constants/text-constants.ts index 83dd251f..f0b2143d 100644 --- a/apps/web/src/constants/text-constants.ts +++ b/apps/web/src/constants/text-constants.ts @@ -1,38 +1,40 @@ -import type { TextElement } from "@/types/timeline";
-import { TIMELINE_CONSTANTS } from "./timeline-constants";
-
-export const MIN_FONT_SIZE = 5;
-export const MAX_FONT_SIZE = 300;
-
-/**
- * higher value: smaller font size
- * lower value: larger font size
- */
-export const FONT_SIZE_SCALE_REFERENCE = 90;
-
-export const DEFAULT_TEXT_ELEMENT: Omit<TextElement, "id"> = {
- type: "text",
- name: "Text",
- content: "Default text",
- fontSize: 15,
- fontFamily: "Arial",
- color: "#ffffff",
- backgroundColor: "transparent",
- textAlign: "center",
- fontWeight: "normal",
- fontStyle: "normal",
- textDecoration: "none",
- duration: TIMELINE_CONSTANTS.DEFAULT_ELEMENT_DURATION,
- startTime: 0,
- trimStart: 0,
- trimEnd: 0,
- transform: {
- scale: 1,
- position: {
- x: 0,
- y: 0,
- },
- rotate: 0,
- },
- opacity: 1,
-};
+import type { TextElement } from "@/types/timeline"; +import { + DEFAULT_OPACITY, + DEFAULT_TRANSFORM, + TIMELINE_CONSTANTS, +} from "./timeline-constants"; + +export const MIN_FONT_SIZE = 5; +export const MAX_FONT_SIZE = 300; + +/** + * higher value: smaller font size + * lower value: larger font size + */ +export const FONT_SIZE_SCALE_REFERENCE = 90; + +export const DEFAULT_LETTER_SPACING = 0; +export const DEFAULT_LINE_HEIGHT = 1.2; + +export const DEFAULT_TEXT_ELEMENT: Omit<TextElement, "id"> = { + type: "text", + name: "Text", + content: "Default text", + fontSize: 15, + fontFamily: "Arial", + color: "#ffffff", + backgroundColor: "#000000", + textAlign: "center", + fontWeight: "normal", + fontStyle: "normal", + textDecoration: "none", + letterSpacing: DEFAULT_LETTER_SPACING, + lineHeight: DEFAULT_LINE_HEIGHT, + duration: TIMELINE_CONSTANTS.DEFAULT_ELEMENT_DURATION, + startTime: 0, + trimStart: 0, + trimEnd: 0, + transform: DEFAULT_TRANSFORM, + opacity: DEFAULT_OPACITY, +}; diff --git a/apps/web/src/constants/timeline-constants.tsx b/apps/web/src/constants/timeline-constants.tsx index d6af3c3a..5ac0913a 100644 --- a/apps/web/src/constants/timeline-constants.tsx +++ b/apps/web/src/constants/timeline-constants.tsx @@ -1,5 +1,6 @@ import type { TTimelineViewState } from "@/types/project"; -import type { TrackType } from "@/types/timeline"; +import type { BlendMode } from "@/types/rendering"; +import type { TrackType, Transform } from "@/types/timeline"; import { Happy01Icon, MusicNote03Icon, @@ -8,6 +9,16 @@ import { import { HugeiconsIcon } from "@hugeicons/react"; import { OcVideoIcon } from "@opencut/ui/icons"; +export const DEFAULT_TRANSFORM: Transform = { + scale: 1, + position: { x: 0, y: 0 }, + rotate: 0, +}; + +export const DEFAULT_OPACITY = 1; +export const DEFAULT_BLEND_MODE: BlendMode = "normal"; +export const DEFAULT_BOOKMARK_COLOR = "#009dff"; + export const TRACK_COLORS: Record<TrackType, { background: string }> = { video: { background: "transparent", @@ -32,6 +43,8 @@ export const TRACK_HEIGHTS: Record<TrackType, number> = { export const TRACK_GAP = 4; +export const DRAG_THRESHOLD_PX = 5; + export const TIMELINE_CONSTANTS = { PIXELS_PER_SECOND: 50, DEFAULT_ELEMENT_DURATION: 5, |
