Components
Loading preview...
"Digital Glitch" effect, reminiscent of retro CRT monitors and cyberpunk visuals. It moves away from the previous organic noise to a more geometric and distorted style. I've built it with the same high-quality, performant structure as before. You now have controls for Glitch Intensity, RGB Shift, and Scanline Density, along with new presets like "Damaged VCR" and "Cyberpunk" to showcase the different effects you can create.
@dhiluxui
npx shadcn@latest add https://21st.dev/r/dhileepkumargm/digital-glitchimport React, { useState, useCallback } from 'react';
import ShaderCanvas from "@/components/ui/digital-glitch";
// --- Constants ---
const DEFAULT_PROPS = {
baseColor: "#ffffff",
speed: 0.3,
glitchIntensity: 0.5,
rgbShift: 0.01,
scanlineDensity: 800.0,
scanlineOpacity: 0.2,
};
const PRESETS = [
{ name: "Subtle Interference", settings: { baseColor: "#a7f3d0", speed: 0.2, glitchIntensity: 0.2, rgbShift: 0.002, scanlineDensity: 1000.0, scanlineOpacity: 0.1 } },
{ name: "Damaged VCR", settings: { baseColor: "#fde047", speed: 0.1, glitchIntensity: 1.0, rgbShift: 0.02, scanlineDensity: 400.0, scanlineOpacity: 0.35 } },
{ name: "Cyberpunk", settings: { baseColor: "#ec4899", speed: 0.5, glitchIntensity: 0.6, rgbShift: 0.015, scanlineDensity: 600.0, scanlineOpacity: 0.15 } },
];
export default function DemoOne() {
const [props, setProps] = useState(DEFAULT_PROPS);
const applyPreset = useCallback((preset) => {
setProps(preset.settings);
}, []);
const handleValueChange = useCallback((propName, value) => {
setProps(prev => ({ ...prev, [propName]: value }));
}, []);
return (
<div className="relative w-screen h-screen bg-black font-sans overflow-hidden">
<ShaderCanvas {...props} />
<div className="absolute top-4 right-4 bg-black/40 backdrop-blur-xl p-6 rounded-2xl text-white shadow-2xl w-96 border border-white/10">
<h1 className="text-2xl font-bold mb-2 tracking-wide text-white/90">Digital Glitch Controls</h1>
<p className="text-xs text-white/50 mb-4">A retro CRT-style shader</p>
<div className="mb-4">
<label htmlFor="baseColor" className="block mb-2 text-sm font-medium text-white/70">Base Color</label>
<input id="baseColor" type="color" value={props.baseColor} onChange={(e) => handleValueChange('baseColor', e.target.value)} className="w-full h-10 p-1 bg-gray-800 border border-white/20 rounded-md cursor-pointer"/>
</div>
<div className="space-y-4">
<div>
<label htmlFor="speed" className="block mb-1 text-sm font-medium text-white/70">Speed: {props.speed.toFixed(2)}</label>
<input id="speed" type="range" min="0.0" max="1.0" step="0.01" value={props.speed} onChange={(e) => handleValueChange('speed', parseFloat(e.target.value))} className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-pink-500"/>
</div>
<div>
<label htmlFor="glitchIntensity" className="block mb-1 text-sm font-medium text-white/70">Glitch Intensity: {props.glitchIntensity.toFixed(2)}</label>
<input id="glitchIntensity" type="range" min="0.0" max="1.0" step="0.01" value={props.glitchIntensity} onChange={(e) => handleValueChange('glitchIntensity', parseFloat(e.target.value))} className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-pink-500"/>
</div>
<div>
<label htmlFor="rgbShift" className="block mb-1 text-sm font-medium text-white/70">RGB Shift: {props.rgbShift.toFixed(3)}</label>
<input id="rgbShift" type="range" min="0.0" max="0.05" step="0.001" value={props.rgbShift} onChange={(e) => handleValueChange('rgbShift', parseFloat(e.target.value))} className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-pink-500"/>
</div>
<div>
<label htmlFor="scanlineDensity" className="block mb-1 text-sm font-medium text-white/70">Scanline Density: {props.scanlineDensity.toFixed(0)}</label>
<input id="scanlineDensity" type="range" min="100" max="2000" step="10" value={props.scanlineDensity} onChange={(e) => handleValueChange('scanlineDensity', parseFloat(e.target.value))} className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-pink-500"/>
</div>
<div>
<label htmlFor="scanlineOpacity" className="block mb-1 text-sm font-medium text-white/70">Scanline Opacity: {props.scanlineOpacity.toFixed(2)}</label>
<input id="scanlineOpacity" type="range" min="0.0" max="1.0" step="0.01" value={props.scanlineOpacity} onChange={(e) => handleValueChange('scanlineOpacity', parseFloat(e.target.value))} className="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer accent-pink-500"/>
</div>
</div>
<div className="mt-6 pt-4 border-t border-white/10">
<label className="block mb-2 text-sm font-medium text-white/70">Presets</label>
<div className="grid grid-cols-2 gap-2">
{PRESETS.map(p => <button key={p.name} onClick={() => applyPreset(p)} className="px-3 py-2 text-sm bg-white/10 rounded-md hover:bg-white/20 transition-colors duration-200">{p.name}</button>)}
<button onClick={() => setProps(DEFAULT_PROPS)} className="px-3 py-2 text-sm bg-indigo-500/20 text-indigo-300 rounded-md hover:bg-indigo-500/40 transition-colors duration-200 col-span-2">Reset to Default</button>
</div>
</div>
</div>
</div>
);
}