dither-gradient
componentry/dither-gradientFreeComponent
An animated dithered gradient background effect using canvas with Bayer matrix dithering.
Live preview
live · rendered by the registry
Rendered by componentry on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://componentry.dev/r/dither-gradient.jsonSource
1"use client"23import { useEffect, useRef } from "react"4import { cn } from "@/lib/utils"56interface DitherGradientProps {7 className?: string8 colorFrom?: string9 colorTo?: string10 colorMid?: string11 intensity?: number12 speed?: number13 angle?: number14}1516export function DitherGradient({17 className,18 colorFrom = "#4f46e5",19 colorTo = "#ec4899",20 colorMid = "#a855f7",21 intensity = 0.15,22 speed = 3,23 angle = 45,24}: DitherGradientProps) {25 const canvasRef = useRef<HTMLCanvasElement>(null)26 const animationRef = useRef<number>(0)2728 useEffect(() => {29 const canvas = canvasRef.current30 if (!canvas) return3132 const ctx = canvas.getContext("2d")33 if (!ctx) return3435 const resize = () => {36 const rect = canvas.getBoundingClientRect()37 canvas.width = rect.width38 canvas.height = rect.height39 }4041 resize()42 window.addEventListener("resize", resize)4344 let time = 045 const bayerMatrix = [46 [0, 8, 2, 10],47 [12, 4, 14, 6],48 [3, 11, 1, 9],49 [15, 7, 13, 5],50 ]5152 const hexToRgb = (hex: string) => {53 const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)54 if (!result) return { r: 0, g: 0, b: 0 }55 return {56 r: parseInt(result[1]!, 16),57 g: parseInt(result[2]!, 16),58 b: parseInt(result[3]!, 16),59 }60 }6162 const smoothstep = (t: number) => t * t * (3 - 2 * t)6364 const animate = () => {65 const { width, height } = canvas66 const imageData = ctx.createImageData(width, height)67 const data = imageData.data6869 const from = hexToRgb(colorFrom)70 const mid = hexToRgb(colorMid)71 const to = hexToRgb(colorTo)72 const rad = (angle * Math.PI) / 1807374 for (let y = 0; y < height; y++) {75 for (let x = 0; x < width; x++) {76 const normalizedX = x / width77 const normalizedY = y / height7879 const gradientPos =80 (normalizedX * Math.cos(rad) + normalizedY * Math.sin(rad)) * 0.8 +81 0.1 +82 Math.sin(time * speed * 0.0008) * 0.18384 const clampedPos = Math.max(0, Math.min(1, gradientPos))8586 let r: number, g: number, b: number87 if (clampedPos < 0.5) {88 const t = smoothstep(clampedPos * 2)89 r = from.r + (mid.r - from.r) * t90 g = from.g + (mid.g - from.g) * t91 b = from.b + (mid.b - from.b) * t92 } else {93 const t = smoothstep((clampedPos - 0.5) * 2)94// … truncated
More from componentry
All 59 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Animated Gradientanimated-gradient | componentry | Components | Free | no deps | |
| ASCII Effectascii-effect | componentry | Components | Free | no deps | |
| Aurora Flowaurora-flow | componentry | Components | Free | no deps | |
| auth-modalauth-modal | componentry | Components | Free | no deps | |
| border-beamborder-beam | componentry | Components | Free | no deps | |
| circuit-boardcircuit-board | componentry | Components | Free | no deps | |
| closing-plasmaclosing-plasma | componentry | Components | Free | no deps | |
| collection-surfercollection-surfer | componentry | Components | Free | no deps |
