"use client" import { useState, useEffect } from "react" import { Label } from "@/components/ui/label" import { Slider } from "@/components/ui/slider" import { Switch } from "@/components/ui/switch" import { useTheme } from "next-themes" export function GrainControl() { const [enableGrain, setEnableGrain] = useState(false) const [grainOpacity, setGrainOpacity] = useState(0.05) const [grainSize, setGrainSize] = useState(0.5) const { theme } = useTheme() useEffect(() => { if (typeof window === "undefined") return const root = document.documentElement if (enableGrain) { // Create SVG noise filter const svgNoise = ` ` // Add SVG to document if not already present if (!document.getElementById("noise-svg")) { const div = document.createElement("div") div.id = "noise-svg" div.innerHTML = svgNoise div.style.position = "absolute" div.style.width = "0" div.style.height = "0" div.style.overflow = "hidden" document.body.appendChild(div) } else { document.getElementById("noise-svg")!.innerHTML = svgNoise } // Apply grain effect via CSS root.style.setProperty("--grain-opacity", grainOpacity.toString()) root.style.setProperty("--grain-blend-mode", theme === "dark" ? "overlay" : "soft-light") root.classList.add("grain-effect") } else { root.classList.remove("grain-effect") } return () => { // Cleanup const noiseSvg = document.getElementById("noise-svg") if (noiseSvg && !enableGrain) { noiseSvg.remove() } } }, [enableGrain, grainOpacity, grainSize, theme]) return (

Grain Texture

{enableGrain && (
{Math.round(grainOpacity * 100)}%
setGrainOpacity(value[0])} />
{grainSize < 0.3 ? "Fine" : grainSize < 0.7 ? "Medium" : "Coarse"}
setGrainSize(value[0])} />
)}
) }