diff --git a/package-lock.json b/package-lock.json index 1327091..693b58b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", + "@uiw/react-color-colorful": "^2.9.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.545.0", @@ -309,6 +310,16 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", @@ -2600,6 +2611,106 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@uiw/color-convert": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/color-convert/-/color-convert-2.9.0.tgz", + "integrity": "sha512-tFm6iac8iN3VL9IIAXKAVpBX6ZQH7ucCvb+EgZNM5y8prRWlk53cERnP4RycE3wnYb/HUKW0lrngoygQnEWAHg==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0" + } + }, + "node_modules/@uiw/react-color-alpha": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/react-color-alpha/-/react-color-alpha-2.9.0.tgz", + "integrity": "sha512-tP9zs2KUPzIGvdtTBTNlDEdwHWcNJ3Ju/nnpPTsKERRJF2vzucb3v18JzihX0ACiOXU9+JVqgpAVgvoZXMeITA==", + "license": "MIT", + "dependencies": { + "@uiw/color-convert": "2.9.0", + "@uiw/react-drag-event-interactive": "2.9.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-colorful": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/react-color-colorful/-/react-color-colorful-2.9.0.tgz", + "integrity": "sha512-qw7zhgX9J4aydK0hKKLroXMYp0tw3ASNuZM1fQNwXXIpOkEW4zO+PHTkzUBpbII68wGS8tAxsZessTWNpAVi0w==", + "license": "MIT", + "dependencies": { + "@uiw/color-convert": "2.9.0", + "@uiw/react-color-alpha": "2.9.0", + "@uiw/react-color-hue": "2.9.0", + "@uiw/react-color-saturation": "2.9.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-hue": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/react-color-hue/-/react-color-hue-2.9.0.tgz", + "integrity": "sha512-2Ix027ref3ppiVq+OQkbyKr6O8fLTH+n0wEW4xhHfa3kV8mBa2bEu8jAjrkSwO6uElaE6OJcuqYe2llyKRlIFg==", + "license": "MIT", + "dependencies": { + "@uiw/color-convert": "2.9.0", + "@uiw/react-color-alpha": "2.9.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-color-saturation": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/react-color-saturation/-/react-color-saturation-2.9.0.tgz", + "integrity": "sha512-tBARqsW0ap+gwByGKSid1nYaGJd6dw2MTMwCABF9rebPQHtYbN/YgBjl9dNnp6XDGd+VBhH4RbpM38WV7J1F4g==", + "license": "MIT", + "dependencies": { + "@uiw/color-convert": "2.9.0", + "@uiw/react-drag-event-interactive": "2.9.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@uiw/react-drag-event-interactive": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@uiw/react-drag-event-interactive/-/react-drag-event-interactive-2.9.0.tgz", + "integrity": "sha512-oBqrClsSuYA3IjkSHp4uHOBLgPkR98KeKeheqCRltF8w/a1CPaFCl43pyKyxwXaTV6qM6cb3VkT3JRCHMNqTzA==", + "license": "MIT", + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + }, + "peerDependencies": { + "@babel/runtime": ">=7.19.0", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", diff --git a/package.json b/package.json index d8d90cf..47b55c7 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", + "@uiw/react-color-colorful": "^2.9.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "lucide-react": "^0.545.0", diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 85cbe57..24aef1a 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -1,50 +1,100 @@ import { cn } from "@/lib/utils"; import { Switch } from "@/components/ui/switch"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { useState } from "react"; +import Colorful from '@uiw/react-color-colorful'; +import { hsvaToHex } from '@uiw/color-convert'; const WALLPAPER_COUNT = 12; const WALLPAPER_PATHS = Array.from({ length: WALLPAPER_COUNT }, (_, i) => `/wallpapers/wallpaper${i + 1}.jpg`); +const GRADIENTS = [ + "linear-gradient( 111.6deg, rgba(114,167,232,1) 9.4%, rgba(253,129,82,1) 43.9%, rgba(253,129,82,1) 54.8%, rgba(249,202,86,1) 86.3% )", + "linear-gradient(120deg, #d4fc79 0%, #96e6a1 100%)", + "radial-gradient( circle farthest-corner at 3.2% 49.6%, rgba(80,12,139,0.87) 0%, rgba(161,10,144,0.72) 83.6% )", + "linear-gradient( 111.6deg, rgba(0,56,68,1) 0%, rgba(163,217,185,1) 51.5%, rgba(231, 148, 6, 1) 88.6% )", + "linear-gradient( 107.7deg, rgba(235,230,44,0.55) 8.4%, rgba(252,152,15,1) 90.3% )", + "linear-gradient( 91deg, rgba(72,154,78,1) 5.2%, rgba(251,206,70,1) 95.9% )", + "radial-gradient( circle farthest-corner at 10% 20%, rgba(2,37,78,1) 0%, rgba(4,56,126,1) 19.7%, rgba(85,245,221,1) 100.2% )", + "linear-gradient( 109.6deg, rgba(15,2,2,1) 11.2%, rgba(36,163,190,1) 91.1% )", + "linear-gradient(135deg, #FBC8B4, #2447B1)", + "linear-gradient(109.6deg, #F635A6, #36D860)", + "linear-gradient(90deg, #FF0101, #4DFF01)", + "linear-gradient(315deg, #EC0101, #5044A9)", +]; interface SettingsPanelProps { selected: string; onWallpaperChange: (path: string) => void; - shadowEnabled: boolean; - onShadowChange: (enabled: boolean) => void; } -export default function SettingsPanel({ selected, onWallpaperChange, shadowEnabled, onShadowChange }: SettingsPanelProps) { +export default function SettingsPanel({ selected, onWallpaperChange }: SettingsPanelProps) { + const [hsva, setHsva] = useState({ h: 0, s: 0, v: 68, a: 1 }); + const [gradient, setGradient] = useState(GRADIENTS[0]); + return (
- +
Shadow
-
-
Choose Background
-
- {WALLPAPER_PATHS.map((path, idx) => ( -
onWallpaperChange(path)} - onKeyDown={e => { if (e.key === 'Enter' || e.key === ' ') onWallpaperChange(path); }} - role="button" - /> - ))} -
-
-
- Settings -
+ + + Image + Color + Gradient + + + +
+ {WALLPAPER_PATHS.map((path, idx) => ( +
onWallpaperChange(path)} + role="button" + /> + ))} +
+ + + + { + setHsva(color.hsva); + onWallpaperChange(hsvaToHex(color.hsva)); + }} + /> + + + +
+ {GRADIENTS.map((g, idx) => ( +
{ setGradient(g); onWallpaperChange(g); }} + role="button" + /> + ))} +
+ +
); } diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index 1390fe0..3e9b2cd 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -112,10 +112,15 @@ const VideoPlayback = forwardRef(({ } }; + const isImageUrl = wallpaper?.startsWith('/wallpapers/') || wallpaper?.startsWith('http'); + const backgroundStyle = isImageUrl + ? { backgroundImage: `url(${wallpaper || '/wallpapers/wallpaper1.jpg'})` } + : { background: wallpaper || '/wallpapers/wallpaper1.jpg' }; + return (