{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "Aurora-JS-TW", "type": "registry:block", "title": "Aurora", "description": "Flowing aurora gradient background.", "dependencies": [ "ogl" ], "files": [ { "path": "public/tailwind/src/tailwind/Backgrounds/Aurora/Aurora.jsx", "content": "import { Renderer, Program, Mesh, Color, Triangle } from 'ogl';\r\nimport { useEffect, useRef } from 'react';\r\n\r\nconst VERT = `#version 300 es\r\nin vec2 position;\r\nvoid main() {\r\n gl_Position = vec4(position, 0.0, 1.0);\r\n}\r\n`;\r\n\r\nconst FRAG = `#version 300 es\r\nprecision highp float;\r\n\r\nuniform float uTime;\r\nuniform float uAmplitude;\r\nuniform vec3 uColorStops[3];\r\nuniform vec2 uResolution;\r\nuniform float uBlend;\r\n\r\nout vec4 fragColor;\r\n\r\nvec3 permute(vec3 x) {\r\n return mod(((x * 34.0) + 1.0) * x, 289.0);\r\n}\r\n\r\nfloat snoise(vec2 v){\r\n const vec4 C = vec4(\r\n 0.211324865405187, 0.366025403784439,\r\n -0.577350269189626, 0.024390243902439\r\n );\r\n vec2 i = floor(v + dot(v, C.yy));\r\n vec2 x0 = v - i + dot(i, C.xx);\r\n vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\r\n vec4 x12 = x0.xyxy + C.xxzz;\r\n x12.xy -= i1;\r\n i = mod(i, 289.0);\r\n\r\n vec3 p = permute(\r\n permute(i.y + vec3(0.0, i1.y, 1.0))\r\n + i.x + vec3(0.0, i1.x, 1.0)\r\n );\r\n\r\n vec3 m = max(\r\n 0.5 - vec3(\r\n dot(x0, x0),\r\n dot(x12.xy, x12.xy),\r\n dot(x12.zw, x12.zw)\r\n ), \r\n 0.0\r\n );\r\n m = m * m;\r\n m = m * m;\r\n\r\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\r\n vec3 h = abs(x) - 0.5;\r\n vec3 ox = floor(x + 0.5);\r\n vec3 a0 = x - ox;\r\n m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);\r\n\r\n vec3 g;\r\n g.x = a0.x * x0.x + h.x * x0.y;\r\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\r\n return 130.0 * dot(m, g);\r\n}\r\n\r\nstruct ColorStop {\r\n vec3 color;\r\n float position;\r\n};\r\n\r\n#define COLOR_RAMP(colors, factor, finalColor) { \\\r\n int index = 0; \\\r\n for (int i = 0; i < 2; i++) { \\\r\n ColorStop currentColor = colors[i]; \\\r\n bool isInBetween = currentColor.position <= factor; \\\r\n index = int(mix(float(index), float(i), float(isInBetween))); \\\r\n } \\\r\n ColorStop currentColor = colors[index]; \\\r\n ColorStop nextColor = colors[index + 1]; \\\r\n float range = nextColor.position - currentColor.position; \\\r\n float lerpFactor = (factor - currentColor.position) / range; \\\r\n finalColor = mix(currentColor.color, nextColor.color, lerpFactor); \\\r\n}\r\n\r\nvoid main() {\r\n vec2 uv = gl_FragCoord.xy / uResolution;\r\n \r\n ColorStop colors[3];\r\n colors[0] = ColorStop(uColorStops[0], 0.0);\r\n colors[1] = ColorStop(uColorStops[1], 0.5);\r\n colors[2] = ColorStop(uColorStops[2], 1.0);\r\n \r\n vec3 rampColor;\r\n COLOR_RAMP(colors, uv.x, rampColor);\r\n \r\n float height = snoise(vec2(uv.x * 2.0 + uTime * 0.1, uTime * 0.25)) * 0.5 * uAmplitude;\r\n height = exp(height);\r\n height = (uv.y * 2.0 - height + 0.2);\r\n float intensity = 0.6 * height;\r\n \r\n float midPoint = 0.20;\r\n float auroraAlpha = smoothstep(midPoint - uBlend * 0.5, midPoint + uBlend * 0.5, intensity);\r\n \r\n vec3 auroraColor = intensity * rampColor;\r\n \r\n fragColor = vec4(auroraColor * auroraAlpha, auroraAlpha);\r\n}\r\n`;\r\n\r\nexport default function Aurora(props) {\r\n const { colorStops = ['#5227FF', '#7cff67', '#5227FF'], amplitude = 1.0, blend = 0.5 } = props;\r\n const propsRef = useRef(props);\r\n propsRef.current = props;\r\n\r\n const ctnDom = useRef(null);\r\n\r\n useEffect(() => {\r\n const ctn = ctnDom.current;\r\n if (!ctn) return;\r\n\r\n const renderer = new Renderer({\r\n alpha: true,\r\n premultipliedAlpha: true,\r\n antialias: true\r\n });\r\n const gl = renderer.gl;\r\n gl.clearColor(0, 0, 0, 0);\r\n gl.enable(gl.BLEND);\r\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\r\n gl.canvas.style.backgroundColor = 'transparent';\r\n\r\n let program;\r\n\r\n function resize() {\r\n if (!ctn) return;\r\n const width = ctn.offsetWidth;\r\n const height = ctn.offsetHeight;\r\n renderer.setSize(width, height);\r\n if (program) {\r\n program.uniforms.uResolution.value = [width, height];\r\n }\r\n }\r\n window.addEventListener('resize', resize);\r\n\r\n const geometry = new Triangle(gl);\r\n if (geometry.attributes.uv) {\r\n delete geometry.attributes.uv;\r\n }\r\n\r\n const colorStopsArray = colorStops.map(hex => {\r\n const c = new Color(hex);\r\n return [c.r, c.g, c.b];\r\n });\r\n\r\n program = new Program(gl, {\r\n vertex: VERT,\r\n fragment: FRAG,\r\n uniforms: {\r\n uTime: { value: 0 },\r\n uAmplitude: { value: amplitude },\r\n uColorStops: { value: colorStopsArray },\r\n uResolution: { value: [ctn.offsetWidth, ctn.offsetHeight] },\r\n uBlend: { value: blend }\r\n }\r\n });\r\n\r\n const mesh = new Mesh(gl, { geometry, program });\r\n ctn.appendChild(gl.canvas);\r\n\r\n let animateId = 0;\r\n const update = t => {\r\n animateId = requestAnimationFrame(update);\r\n const { time = t * 0.01, speed = 1.0 } = propsRef.current;\r\n program.uniforms.uTime.value = time * speed * 0.1;\r\n program.uniforms.uAmplitude.value = propsRef.current.amplitude ?? 1.0;\r\n program.uniforms.uBlend.value = propsRef.current.blend ?? blend;\r\n const stops = propsRef.current.colorStops ?? colorStops;\r\n program.uniforms.uColorStops.value = stops.map(hex => {\r\n const c = new Color(hex);\r\n return [c.r, c.g, c.b];\r\n });\r\n renderer.render({ scene: mesh });\r\n };\r\n animateId = requestAnimationFrame(update);\r\n\r\n resize();\r\n\r\n return () => {\r\n cancelAnimationFrame(animateId);\r\n window.removeEventListener('resize', resize);\r\n if (ctn && gl.canvas.parentNode === ctn) {\r\n ctn.removeChild(gl.canvas);\r\n }\r\n gl.getExtension('WEBGL_lose_context')?.loseContext();\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [amplitude]);\r\n\r\n return
;\r\n}\r\n", "type": "registry:component" } ] }