From c46d28891fee62ca2d3132da876af6411a41d9da Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Wed, 15 Apr 2026 15:45:50 +0200 Subject: feat: text / custom masks, fix preview pan, refactor selection --- .../panels/assets/views/settings/background.tsx | 542 ++++++++++++--------- 1 file changed, 309 insertions(+), 233 deletions(-) (limited to 'apps/web/src/components/editor/panels/assets') diff --git a/apps/web/src/components/editor/panels/assets/views/settings/background.tsx b/apps/web/src/components/editor/panels/assets/views/settings/background.tsx index 98847453..099e335a 100644 --- a/apps/web/src/components/editor/panels/assets/views/settings/background.tsx +++ b/apps/web/src/components/editor/panels/assets/views/settings/background.tsx @@ -1,233 +1,309 @@ -"use client"; - -import { memo, useCallback, useEffect, useMemo, useRef } from "react"; -import { - Section, - SectionContent, - SectionHeader, - SectionTitle, -} from "@/components/section"; -import { - BACKGROUND_BLUR_INTENSITY_PRESETS, - DEFAULT_BACKGROUND_BLUR_INTENSITY, -} from "@/lib/background/blur"; -import { DEFAULT_BACKGROUND_COLOR } from "@/lib/background/color"; -import { patternCraftGradients } from "@/data/colors/pattern-craft"; -import { colors } from "@/data/colors/solid"; -import { syntaxUIGradients } from "@/data/colors/syntax-ui"; -import { useEditor } from "@/hooks/use-editor"; -import { effectPreviewService } from "@/services/renderer/effect-preview"; -import { cn } from "@/utils/ui"; - -const BLUR_PREVIEW_UNIFORM_DIMENSIONS = { - width: 1920, - height: 1080, -} as const; - -const BlurPreview = memo( - ({ - blur, - isSelected, - onSelect, - }: { - blur: { label: string; value: number }; - isSelected: boolean; - onSelect: () => void; - }) => { - const canvasRef = useRef(null); - - useEffect(() => { - const renderPreview = () => { - if (!canvasRef.current) return; - - effectPreviewService.renderPreview({ - effectType: "blur", - params: { intensity: blur.value }, - targetCanvas: canvasRef.current, - uniformDimensions: BLUR_PREVIEW_UNIFORM_DIMENSIONS, - }); - }; - - renderPreview(); - return effectPreviewService.onPreviewImageReady({ - callback: renderPreview, - }); - }, [blur.value]); - - return ( - - ); - }, -); - -BlurPreview.displayName = "BlurPreview"; - -const BackgroundPreviews = memo( - ({ - backgrounds, - currentBackgroundColor, - isColorBackground, - onSelect, - useBackgroundColor = false, - }: { - backgrounds: string[]; - currentBackgroundColor: string; - isColorBackground: boolean; - onSelect: (bg: string) => void; - useBackgroundColor?: boolean; - }) => { - return useMemo( - () => - backgrounds.map((bg) => ( - + ); + }, +); + +BlurPreview.displayName = "BlurPreview"; + +const BackgroundPreviews = memo( + ({ + backgrounds, + currentBackgroundColor, + isColorBackground, + onSelect, + useBackgroundColor = false, + }: { + backgrounds: readonly string[]; + currentBackgroundColor: string; + isColorBackground: boolean; + onSelect: (bg: string) => void; + useBackgroundColor?: boolean; + }) => { + return useMemo( + () => + backgrounds.map((bg) => ( + + + onPreview(`#${color}`)} + onChangeEnd={(color) => onCommit(`#${color}`)} + /> + + ); +} + +const COLOR_SECTIONS = [ + { id: "colors", title: "Colors", backgrounds: colors, useBackgroundColor: true, showCustomPicker: true }, + { id: "pattern-craft", title: "Pattern craft", backgrounds: patternCraftGradients, showCustomPicker: false }, + { id: "syntax-ui", title: "Syntax UI", backgrounds: syntaxUIGradients, showCustomPicker: false }, +] as const; + +export function BackgroundContent() { + const editor = useEditor(); + const activeProject = useEditor((e) => e.project.getActive()); + + const handleBlurSelect = useCallback( + async (blurIntensity: number) => { + await editor.project.updateSettings({ + settings: { background: { type: "blur", blurIntensity } }, + }); + }, + [editor.project], + ); + + const previewBackgroundColor = useCallback( + async (color: string) => { + await editor.project.updateSettings({ + settings: { background: { type: "color", color } }, + pushHistory: false, + }); + }, + [editor.project], + ); + + const commitBackgroundColor = useCallback( + async (color: string) => { + await editor.project.updateSettings({ + settings: { background: { type: "color", color } }, + pushHistory: true, + }); + }, + [editor.project], + ); + + const isBlurBackground = activeProject.settings.background.type === "blur"; + const isColorBackground = activeProject.settings.background.type === "color"; + + const currentBlurIntensity = isBlurBackground + ? (activeProject.settings.background as { blurIntensity: number }) + .blurIntensity + : DEFAULT_BACKGROUND_BLUR_INTENSITY; + + const currentBackgroundColor = isColorBackground + ? (activeProject.settings.background as { color: string }).color + : DEFAULT_BACKGROUND_COLOR; + + const hasPresetColorMatch = colors.some( + (color) => color.toLowerCase() === currentBackgroundColor.toLowerCase(), + ); + + const handlePresetColorSelect = useCallback( + (color: string) => { + void commitBackgroundColor(color); + }, + [commitBackgroundColor], + ); + + const blurPreviews = useMemo( + () => + BACKGROUND_BLUR_INTENSITY_PRESETS.map((blur) => ( + handleBlurSelect(blur.value)} + /> + )), + [isBlurBackground, currentBlurIntensity, handleBlurSelect], + ); + + return ( +
+
+ + Blur + + +
{blurPreviews}
+
+
+ {COLOR_SECTIONS.map((section) => ( +
+ + {section.title} + + +
+ {section.showCustomPicker ? ( + + ) : null} + +
+
+
+ ))} +
+ ); +} -- cgit v1.3.1