{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "gradient-utils", "title": "Gradient Utils", "description": "Generate random, aesthetically balanced gradients in the OKLCH color space and render them to CSS.", "dependencies": [], "registryDependencies": [], "files": [ { "path": "lib/gradient-utils.ts", "content": "/**\n * Utility functions for generating random gradient backgrounds (OKLCH color space)\n */\n\nexport interface GradientColor {\n /** Lightness (0-100%) */\n l: number;\n /** Chroma (0-0.4) */\n c: number;\n /** Hue (0-360) */\n h: number;\n}\n\nexport interface Gradient {\n colors: GradientColor[];\n angle: number;\n stops: number[];\n}\n\n/**\n * Generate a random color in OKLCH\n */\nexport function randomColor(): GradientColor {\n return {\n l: Math.random() * 60 + 30, // 30-90% lightness\n c: Math.random() * 0.25 + 0.05, // 0.05-0.30 chroma\n h: Math.random() * 360, // full hue range\n };\n}\n\n/**\n * Generate a random gradient with 2-4 colors\n */\nexport function generateRandomGradient(): Gradient {\n const numColors = Math.floor(Math.random() * 3) + 2;\n const colors: GradientColor[] = [];\n const stops: number[] = [];\n\n for (let i = 0; i < numColors; i++) {\n colors.push(randomColor());\n stops.push((i / (numColors - 1)) * 100);\n }\n\n const angle = Math.floor(Math.random() * 360);\n\n return {\n colors,\n angle,\n stops,\n };\n}\n\n/**\n * Convert gradient to CSS linear-gradient string (oklch)\n */\nexport function gradientToCSS(gradient: Gradient): string {\n const colorStops = gradient.colors\n .map((color, index) => {\n const stop = gradient.stops[index];\n return `oklch(${color.l.toFixed(1)}% ${color.c.toFixed(3)} ${color.h.toFixed(1)} / 0.8) ${stop}%`;\n })\n .join(\", \");\n\n return `linear-gradient(${gradient.angle}deg in oklch, ${colorStops})`;\n}\n\n/**\n * Generate a seeded random gradient based on a string (for consistent per-page gradients)\n */\nexport function generateSeededGradient(seed: string): Gradient {\n let hash = 0;\n for (let i = 0; i < seed.length; i++) {\n const char = seed.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const rng = (seed: number) => {\n const x = Math.sin(seed) * 10000;\n return x - Math.floor(x);\n };\n\n const numColors = Math.floor(rng(hash) * 3) + 2;\n const colors: GradientColor[] = [];\n const stops: number[] = [];\n\n for (let i = 0; i < numColors; i++) {\n const colorHash = hash + i * 1000;\n colors.push({\n l: rng(colorHash) * 60 + 30,\n c: rng(colorHash + 1) * 0.25 + 0.05,\n h: rng(colorHash + 2) * 360,\n });\n stops.push((i / (numColors - 1)) * 100);\n }\n\n const angle = Math.floor(rng(hash + 10000) * 360);\n\n return {\n colors,\n angle,\n stops,\n };\n}\n\nexport type GradientScheme = \"complementary\" | \"analogous\" | \"triadic\" | \"monochromatic\";\n\nconst wrapHue = (h: number) => ((h % 360) + 360) % 360;\n\n/**\n * Generate a beautiful gradient. `scheme` controls the hue relationship between the\n * three stops; `baseHue` fixes the lead color (omit for a random hue).\n */\nexport function generateBeautifulGradient(baseHue?: number, scheme: GradientScheme = \"complementary\"): Gradient {\n const hue = baseHue ?? Math.random() * 360;\n\n let colors: GradientColor[];\n switch (scheme) {\n case \"analogous\":\n colors = [\n {\n l: 62,\n c: 0.19,\n h: wrapHue(hue - 35),\n },\n {\n l: 66,\n c: 0.2,\n h: hue,\n },\n {\n l: 70,\n c: 0.18,\n h: wrapHue(hue + 35),\n },\n ];\n break;\n case \"triadic\":\n colors = [\n {\n l: 64,\n c: 0.2,\n h: hue,\n },\n {\n l: 66,\n c: 0.19,\n h: wrapHue(hue + 120),\n },\n {\n l: 68,\n c: 0.18,\n h: wrapHue(hue + 240),\n },\n ];\n break;\n case \"monochromatic\":\n colors = [\n {\n l: 52,\n c: 0.22,\n h: hue,\n },\n {\n l: 68,\n c: 0.18,\n h: hue,\n },\n {\n l: 82,\n c: 0.1,\n h: hue,\n },\n ];\n break;\n default:\n colors = [\n {\n l: 65,\n c: 0.2,\n h: hue,\n },\n {\n l: 65,\n c: 0.2,\n h: wrapHue(hue + 180),\n },\n {\n l: 70,\n c: 0.17,\n h: wrapHue(hue + 120),\n },\n ];\n }\n\n const stops = [\n 0,\n 50,\n 100,\n ];\n const angle = Math.floor(Math.random() * 360);\n\n return {\n colors,\n angle,\n stops,\n };\n}\n", "type": "registry:lib", "target": "lib/gradient-utils.ts" } ], "type": "registry:lib" }