From 4d67e366ad23e1d3b23b6bc33d4b4a4eefa6e7c5 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Fri, 11 Jul 2025 03:52:39 +0200 Subject: feat: background settings (color, blur) --- apps/web/src/components/editor/preview-panel.tsx | 100 ++++++++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) (limited to 'apps/web/src/components/editor/preview-panel.tsx') diff --git a/apps/web/src/components/editor/preview-panel.tsx b/apps/web/src/components/editor/preview-panel.tsx index 1cc9d976..2f76af5a 100644 --- a/apps/web/src/components/editor/preview-panel.tsx +++ b/apps/web/src/components/editor/preview-panel.tsx @@ -21,6 +21,8 @@ import { useState, useRef, useEffect } from "react"; import { cn } from "@/lib/utils"; import { formatTimeCode } from "@/lib/time"; import { FONT_CLASS_MAP } from "@/lib/font-config"; +import { BackgroundSettings } from "../background-settings"; +import { useProjectStore } from "@/stores/project-store"; interface ActiveElement { element: TimelineElement; @@ -39,6 +41,7 @@ export function PreviewPanel() { width: 0, height: 0, }); + const { activeProject } = useProjectStore(); // Calculate optimal preview size that fits in container while maintaining aspect ratio useEffect(() => { @@ -136,6 +139,85 @@ export function PreviewPanel() { // Check if there are any elements in the timeline at all const hasAnyElements = tracks.some((track) => track.elements.length > 0); + // Get media elements for blur background (video/image only) + const getBlurBackgroundElements = (): ActiveElement[] => { + return activeElements.filter( + ({ element, mediaItem }) => + element.type === "media" && + mediaItem && + (mediaItem.type === "video" || mediaItem.type === "image") && + element.mediaId !== "test" // Exclude test elements + ); + }; + + const blurBackgroundElements = getBlurBackgroundElements(); + + // Render blur background layer + const renderBlurBackground = () => { + if ( + !activeProject?.backgroundType || + activeProject.backgroundType !== "blur" || + blurBackgroundElements.length === 0 + ) { + return null; + } + + // Use the first media element for background (could be enhanced to use primary/focused element) + const backgroundElement = blurBackgroundElements[0]; + const { element, mediaItem } = backgroundElement; + + if (!mediaItem) return null; + + const blurIntensity = activeProject.blurIntensity || 8; + + if (mediaItem.type === "video") { + return ( +
+ +
+ ); + } + + if (mediaItem.type === "image") { + return ( +
+ {mediaItem.name} +
+ ); + } + + return null; + }; + // Render an element const renderElement = (elementData: ActiveElement, index: number) => { const { element, mediaItem } = elementData; @@ -265,12 +347,17 @@ export function PreviewPanel() { {hasAnyElements ? (
+ {renderBlurBackground()} {activeElements.length === 0 ? (
No elements at current time @@ -280,6 +367,14 @@ export function PreviewPanel() { renderElement(elementData, index) ) )} + {/* Show message when blur is selected but no media available */} + {activeProject?.backgroundType === "blur" && + blurBackgroundElements.length === 0 && + activeElements.length > 0 && ( +
+ Add a video or image to use blur background +
+ )}
) : null} @@ -346,7 +441,8 @@ function PreviewToolbar({ hasAnyElements }: { hasAnyElements: boolean }) { )} -
+
+