From 6334270eb79a294eda34ad2a4f427df784144d7b Mon Sep 17 00:00:00 2001 From: Lin Junrong Date: Fri, 31 Jul 2026 17:53:09 +0800 Subject: [PATCH 1/2] fix(Lightning, RippleGrid): cancel the render loop on cleanup Both components run a self-scheduling requestAnimationFrame loop and never cancel it. The cleanup removes listeners (and RippleGrid even drops the WebGL context and the canvas) but the loop keeps calling into GL every frame after unmount, holding the context, program and closure state alive. Lightning is worse: its effect depends on [hue, xOffset, speed, intensity, size], so every prop change starts another loop without stopping the previous one. Captures the frame id and cancels it in the cleanup. All four variants. --- src/content/Backgrounds/Lightning/Lightning.jsx | 6 ++++-- src/content/Backgrounds/RippleGrid/RippleGrid.jsx | 6 ++++-- src/tailwind/Backgrounds/Lightning/Lightning.jsx | 6 ++++-- src/tailwind/Backgrounds/RippleGrid/RippleGrid.jsx | 6 ++++-- src/ts-default/Backgrounds/Lightning/Lightning.tsx | 6 ++++-- src/ts-default/Backgrounds/RippleGrid/RippleGrid.tsx | 6 ++++-- src/ts-tailwind/Backgrounds/Lightning/Lightning.tsx | 6 ++++-- src/ts-tailwind/Backgrounds/RippleGrid/RippleGrid.tsx | 6 ++++-- 8 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/content/Backgrounds/Lightning/Lightning.jsx b/src/content/Backgrounds/Lightning/Lightning.jsx index d8be403b8..2a3dbe389 100644 --- a/src/content/Backgrounds/Lightning/Lightning.jsx +++ b/src/content/Backgrounds/Lightning/Lightning.jsx @@ -154,6 +154,7 @@ const Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity'); const uSizeLocation = gl.getUniformLocation(program, 'uSize'); + let animationFrameId; const startTime = performance.now(); const render = () => { resizeCanvas(); @@ -167,11 +168,12 @@ const Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 gl.uniform1f(uIntensityLocation, intensity); gl.uniform1f(uSizeLocation, size); gl.drawArrays(gl.TRIANGLES, 0, 6); - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); }; - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); return () => { + cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resizeCanvas); }; }, [hue, xOffset, speed, intensity, size]); diff --git a/src/content/Backgrounds/RippleGrid/RippleGrid.jsx b/src/content/Backgrounds/RippleGrid/RippleGrid.jsx index 755d6c9b7..f24344f05 100644 --- a/src/content/Backgrounds/RippleGrid/RippleGrid.jsx +++ b/src/content/Backgrounds/RippleGrid/RippleGrid.jsx @@ -201,6 +201,7 @@ void main() { } resize(); + let animationFrameId; const render = t => { uniforms.iTime.value = t * 0.001; @@ -215,13 +216,14 @@ void main() { uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y]; renderer.render({ scene: mesh }); - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); }; - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); const container = containerRef.current; return () => { + cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resize); if (mouseInteraction && container) { container.removeEventListener('mousemove', handleMouseMove); diff --git a/src/tailwind/Backgrounds/Lightning/Lightning.jsx b/src/tailwind/Backgrounds/Lightning/Lightning.jsx index 2f5cfaf9c..2beba77e8 100644 --- a/src/tailwind/Backgrounds/Lightning/Lightning.jsx +++ b/src/tailwind/Backgrounds/Lightning/Lightning.jsx @@ -153,6 +153,7 @@ const Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity'); const uSizeLocation = gl.getUniformLocation(program, 'uSize'); + let animationFrameId; const startTime = performance.now(); const render = () => { resizeCanvas(); @@ -166,11 +167,12 @@ const Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 gl.uniform1f(uIntensityLocation, intensity); gl.uniform1f(uSizeLocation, size); gl.drawArrays(gl.TRIANGLES, 0, 6); - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); }; - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); return () => { + cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resizeCanvas); }; }, [hue, xOffset, speed, intensity, size]); diff --git a/src/tailwind/Backgrounds/RippleGrid/RippleGrid.jsx b/src/tailwind/Backgrounds/RippleGrid/RippleGrid.jsx index aa6af2fe0..328678077 100644 --- a/src/tailwind/Backgrounds/RippleGrid/RippleGrid.jsx +++ b/src/tailwind/Backgrounds/RippleGrid/RippleGrid.jsx @@ -200,6 +200,7 @@ void main() { } resize(); + let animationFrameId; const render = t => { uniforms.iTime.value = t * 0.001; @@ -214,13 +215,14 @@ void main() { uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y]; renderer.render({ scene: mesh }); - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); }; - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); const container = containerRef.current; return () => { + cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resize); if (mouseInteraction && container) { container.removeEventListener('mousemove', handleMouseMove); diff --git a/src/ts-default/Backgrounds/Lightning/Lightning.tsx b/src/ts-default/Backgrounds/Lightning/Lightning.tsx index 8b0a14605..7f74b2bda 100644 --- a/src/ts-default/Backgrounds/Lightning/Lightning.tsx +++ b/src/ts-default/Backgrounds/Lightning/Lightning.tsx @@ -162,6 +162,7 @@ const Lightning: React.FC = ({ hue = 230, xOffset = 0, speed = 1 const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity'); const uSizeLocation = gl.getUniformLocation(program, 'uSize'); + let animationFrameId: number; const startTime = performance.now(); const render = () => { resizeCanvas(); @@ -175,11 +176,12 @@ const Lightning: React.FC = ({ hue = 230, xOffset = 0, speed = 1 gl.uniform1f(uIntensityLocation, intensity); gl.uniform1f(uSizeLocation, size); gl.drawArrays(gl.TRIANGLES, 0, 6); - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); }; - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); return () => { + cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resizeCanvas); }; }, [hue, xOffset, speed, intensity, size]); diff --git a/src/ts-default/Backgrounds/RippleGrid/RippleGrid.tsx b/src/ts-default/Backgrounds/RippleGrid/RippleGrid.tsx index 831a5b547..1e5b4cd42 100644 --- a/src/ts-default/Backgrounds/RippleGrid/RippleGrid.tsx +++ b/src/ts-default/Backgrounds/RippleGrid/RippleGrid.tsx @@ -216,6 +216,7 @@ void main() { } resize(); + let animationFrameId: number; const render = (t: number) => { uniforms.iTime.value = t * 0.001; @@ -230,12 +231,13 @@ void main() { uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y]; renderer.render({ scene: mesh }); - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); }; - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); return () => { + cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resize); if (mouseInteraction && containerRef.current) { containerRef.current.removeEventListener('mousemove', handleMouseMove); diff --git a/src/ts-tailwind/Backgrounds/Lightning/Lightning.tsx b/src/ts-tailwind/Backgrounds/Lightning/Lightning.tsx index f4f07eb84..d57f56edc 100644 --- a/src/ts-tailwind/Backgrounds/Lightning/Lightning.tsx +++ b/src/ts-tailwind/Backgrounds/Lightning/Lightning.tsx @@ -161,6 +161,7 @@ const Lightning: React.FC = ({ hue = 230, xOffset = 0, speed = 1 const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity'); const uSizeLocation = gl.getUniformLocation(program, 'uSize'); + let animationFrameId: number; const startTime = performance.now(); const render = () => { resizeCanvas(); @@ -174,11 +175,12 @@ const Lightning: React.FC = ({ hue = 230, xOffset = 0, speed = 1 gl.uniform1f(uIntensityLocation, intensity); gl.uniform1f(uSizeLocation, size); gl.drawArrays(gl.TRIANGLES, 0, 6); - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); }; - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); return () => { + cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resizeCanvas); }; }, [hue, xOffset, speed, intensity, size]); diff --git a/src/ts-tailwind/Backgrounds/RippleGrid/RippleGrid.tsx b/src/ts-tailwind/Backgrounds/RippleGrid/RippleGrid.tsx index 7a0a7d8a7..e249c180f 100644 --- a/src/ts-tailwind/Backgrounds/RippleGrid/RippleGrid.tsx +++ b/src/ts-tailwind/Backgrounds/RippleGrid/RippleGrid.tsx @@ -215,6 +215,7 @@ void main() { } resize(); + let animationFrameId: number; const render = (t: number) => { uniforms.iTime.value = t * 0.001; @@ -229,12 +230,13 @@ void main() { uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y]; renderer.render({ scene: mesh }); - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); }; - requestAnimationFrame(render); + animationFrameId = requestAnimationFrame(render); return () => { + cancelAnimationFrame(animationFrameId); window.removeEventListener('resize', resize); if (mouseInteraction && containerRef.current) { containerRef.current.removeEventListener('mousemove', handleMouseMove); From 02d1a47f5ec5d4bb428a93bb41506dd5bdc6f9a7 Mon Sep 17 00:00:00 2001 From: Lin Junrong Date: Mon, 3 Aug 2026 20:47:13 +0800 Subject: [PATCH 2/2] fix(Lightning, RippleGrid): rebuild the registry artifacts public/r/*.json embeds the component source verbatim and is what the jsrepo CLI writes into a user's project, so a source-only fix still ships the uncancelled rAF loop. Regenerated with `npm run registry:build`. --- public/r/Lightning-JS-CSS.json | 2 +- public/r/Lightning-JS-TW.json | 2 +- public/r/Lightning-TS-CSS.json | 2 +- public/r/Lightning-TS-TW.json | 2 +- public/r/RippleGrid-JS-CSS.json | 2 +- public/r/RippleGrid-JS-TW.json | 2 +- public/r/RippleGrid-TS-CSS.json | 2 +- public/r/RippleGrid-TS-TW.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/public/r/Lightning-JS-CSS.json b/public/r/Lightning-JS-CSS.json index b96123d88..8cb41ecbf 100644 --- a/public/r/Lightning-JS-CSS.json +++ b/public/r/Lightning-JS-CSS.json @@ -13,7 +13,7 @@ { "type": "registry:component", "path": "Lightning/Lightning.jsx", - "content": "import { useRef, useEffect } from 'react';\nimport './Lightning.css';\n\nconst Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const resizeCanvas = () => {\n canvas.width = canvas.clientWidth;\n canvas.height = canvas.clientHeight;\n };\n resizeCanvas();\n window.addEventListener('resize', resizeCanvas);\n\n const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n if (!gl) {\n console.error('WebGL not supported');\n return;\n }\n\n const vertexShaderSource = `\n attribute vec2 aPosition;\n void main() {\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 iResolution;\n uniform float iTime;\n uniform float uHue;\n uniform float uXOffset;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uSize;\n \n #define OCTAVE_COUNT 10\n\n vec3 hsv2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return c.z * mix(vec3(1.0), rgb, c.y);\n }\n\n float hash11(float p) {\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n }\n\n float hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n mat2 rotate2d(float theta) {\n float c = cos(theta);\n float s = sin(theta);\n return mat2(c, -s, s, c);\n }\n\n float noise(vec2 p) {\n vec2 ip = floor(p);\n vec2 fp = fract(p);\n float a = hash12(ip);\n float b = hash12(ip + vec2(1.0, 0.0));\n float c = hash12(ip + vec2(0.0, 1.0));\n float d = hash12(ip + vec2(1.0, 1.0));\n \n vec2 t = smoothstep(0.0, 1.0, fp);\n return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n }\n\n float fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVE_COUNT; ++i) {\n value += amplitude * noise(p);\n p *= rotate2d(0.45);\n p *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n\n void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = fragCoord / iResolution.xy;\n uv = 2.0 * uv - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n uv.x += uXOffset;\n \n uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n \n float dist = abs(uv.x);\n vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n col = pow(col, vec3(1.0));\n float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n fragColor = vec4(col, a);\n }\n\n void main() {\n mainImage(gl_FragColor, gl_FragCoord.xy);\n }\n `;\n\n const compileShader = (source, type) => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n if (!vertexShader || !fragmentShader) return;\n\n const program = gl.createProgram();\n if (!program) return;\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n return;\n }\n gl.useProgram(program);\n\n const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n const vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const aPosition = gl.getAttribLocation(program, 'aPosition');\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n const uHueLocation = gl.getUniformLocation(program, 'uHue');\n const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n const startTime = performance.now();\n const render = () => {\n resizeCanvas();\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n const currentTime = performance.now();\n gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n gl.uniform1f(uHueLocation, hue);\n gl.uniform1f(uXOffsetLocation, xOffset);\n gl.uniform1f(uSpeedLocation, speed);\n gl.uniform1f(uIntensityLocation, intensity);\n gl.uniform1f(uSizeLocation, size);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n requestAnimationFrame(render);\n };\n requestAnimationFrame(render);\n\n return () => {\n window.removeEventListener('resize', resizeCanvas);\n };\n }, [hue, xOffset, speed, intensity, size]);\n\n return ;\n};\n\nexport default Lightning;\n" + "content": "import { useRef, useEffect } from 'react';\nimport './Lightning.css';\n\nconst Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const resizeCanvas = () => {\n canvas.width = canvas.clientWidth;\n canvas.height = canvas.clientHeight;\n };\n resizeCanvas();\n window.addEventListener('resize', resizeCanvas);\n\n const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n if (!gl) {\n console.error('WebGL not supported');\n return;\n }\n\n const vertexShaderSource = `\n attribute vec2 aPosition;\n void main() {\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 iResolution;\n uniform float iTime;\n uniform float uHue;\n uniform float uXOffset;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uSize;\n \n #define OCTAVE_COUNT 10\n\n vec3 hsv2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return c.z * mix(vec3(1.0), rgb, c.y);\n }\n\n float hash11(float p) {\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n }\n\n float hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n mat2 rotate2d(float theta) {\n float c = cos(theta);\n float s = sin(theta);\n return mat2(c, -s, s, c);\n }\n\n float noise(vec2 p) {\n vec2 ip = floor(p);\n vec2 fp = fract(p);\n float a = hash12(ip);\n float b = hash12(ip + vec2(1.0, 0.0));\n float c = hash12(ip + vec2(0.0, 1.0));\n float d = hash12(ip + vec2(1.0, 1.0));\n \n vec2 t = smoothstep(0.0, 1.0, fp);\n return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n }\n\n float fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVE_COUNT; ++i) {\n value += amplitude * noise(p);\n p *= rotate2d(0.45);\n p *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n\n void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = fragCoord / iResolution.xy;\n uv = 2.0 * uv - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n uv.x += uXOffset;\n \n uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n \n float dist = abs(uv.x);\n vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n col = pow(col, vec3(1.0));\n float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n fragColor = vec4(col, a);\n }\n\n void main() {\n mainImage(gl_FragColor, gl_FragCoord.xy);\n }\n `;\n\n const compileShader = (source, type) => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n if (!vertexShader || !fragmentShader) return;\n\n const program = gl.createProgram();\n if (!program) return;\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n return;\n }\n gl.useProgram(program);\n\n const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n const vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const aPosition = gl.getAttribLocation(program, 'aPosition');\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n const uHueLocation = gl.getUniformLocation(program, 'uHue');\n const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n let animationFrameId;\n const startTime = performance.now();\n const render = () => {\n resizeCanvas();\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n const currentTime = performance.now();\n gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n gl.uniform1f(uHueLocation, hue);\n gl.uniform1f(uXOffsetLocation, xOffset);\n gl.uniform1f(uSpeedLocation, speed);\n gl.uniform1f(uIntensityLocation, intensity);\n gl.uniform1f(uSizeLocation, size);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n animationFrameId = requestAnimationFrame(render);\n };\n animationFrameId = requestAnimationFrame(render);\n\n return () => {\n cancelAnimationFrame(animationFrameId);\n window.removeEventListener('resize', resizeCanvas);\n };\n }, [hue, xOffset, speed, intensity, size]);\n\n return ;\n};\n\nexport default Lightning;\n" } ], "registryDependencies": [], diff --git a/public/r/Lightning-JS-TW.json b/public/r/Lightning-JS-TW.json index dcdbf4f54..161fa0a3d 100644 --- a/public/r/Lightning-JS-TW.json +++ b/public/r/Lightning-JS-TW.json @@ -8,7 +8,7 @@ { "type": "registry:component", "path": "Lightning/Lightning.jsx", - "content": "import { useRef, useEffect } from 'react';\n\nconst Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const resizeCanvas = () => {\n canvas.width = canvas.clientWidth;\n canvas.height = canvas.clientHeight;\n };\n resizeCanvas();\n window.addEventListener('resize', resizeCanvas);\n\n const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n if (!gl) {\n console.error('WebGL not supported');\n return;\n }\n\n const vertexShaderSource = `\n attribute vec2 aPosition;\n void main() {\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 iResolution;\n uniform float iTime;\n uniform float uHue;\n uniform float uXOffset;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uSize;\n \n #define OCTAVE_COUNT 10\n\n vec3 hsv2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return c.z * mix(vec3(1.0), rgb, c.y);\n }\n\n float hash11(float p) {\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n }\n\n float hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n mat2 rotate2d(float theta) {\n float c = cos(theta);\n float s = sin(theta);\n return mat2(c, -s, s, c);\n }\n\n float noise(vec2 p) {\n vec2 ip = floor(p);\n vec2 fp = fract(p);\n float a = hash12(ip);\n float b = hash12(ip + vec2(1.0, 0.0));\n float c = hash12(ip + vec2(0.0, 1.0));\n float d = hash12(ip + vec2(1.0, 1.0));\n \n vec2 t = smoothstep(0.0, 1.0, fp);\n return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n }\n\n float fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVE_COUNT; ++i) {\n value += amplitude * noise(p);\n p *= rotate2d(0.45);\n p *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n\n void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = fragCoord / iResolution.xy;\n uv = 2.0 * uv - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n uv.x += uXOffset;\n \n uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n \n float dist = abs(uv.x);\n vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n col = pow(col, vec3(1.0));\n float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n fragColor = vec4(col, a);\n }\n\n void main() {\n mainImage(gl_FragColor, gl_FragCoord.xy);\n }\n `;\n\n const compileShader = (source, type) => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n if (!vertexShader || !fragmentShader) return;\n\n const program = gl.createProgram();\n if (!program) return;\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n return;\n }\n gl.useProgram(program);\n\n const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n const vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const aPosition = gl.getAttribLocation(program, 'aPosition');\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n const uHueLocation = gl.getUniformLocation(program, 'uHue');\n const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n const startTime = performance.now();\n const render = () => {\n resizeCanvas();\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n const currentTime = performance.now();\n gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n gl.uniform1f(uHueLocation, hue);\n gl.uniform1f(uXOffsetLocation, xOffset);\n gl.uniform1f(uSpeedLocation, speed);\n gl.uniform1f(uIntensityLocation, intensity);\n gl.uniform1f(uSizeLocation, size);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n requestAnimationFrame(render);\n };\n requestAnimationFrame(render);\n\n return () => {\n window.removeEventListener('resize', resizeCanvas);\n };\n }, [hue, xOffset, speed, intensity, size]);\n\n return ;\n};\n\nexport default Lightning;\n" + "content": "import { useRef, useEffect } from 'react';\n\nconst Lightning = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const resizeCanvas = () => {\n canvas.width = canvas.clientWidth;\n canvas.height = canvas.clientHeight;\n };\n resizeCanvas();\n window.addEventListener('resize', resizeCanvas);\n\n const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n if (!gl) {\n console.error('WebGL not supported');\n return;\n }\n\n const vertexShaderSource = `\n attribute vec2 aPosition;\n void main() {\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 iResolution;\n uniform float iTime;\n uniform float uHue;\n uniform float uXOffset;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uSize;\n \n #define OCTAVE_COUNT 10\n\n vec3 hsv2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return c.z * mix(vec3(1.0), rgb, c.y);\n }\n\n float hash11(float p) {\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n }\n\n float hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n mat2 rotate2d(float theta) {\n float c = cos(theta);\n float s = sin(theta);\n return mat2(c, -s, s, c);\n }\n\n float noise(vec2 p) {\n vec2 ip = floor(p);\n vec2 fp = fract(p);\n float a = hash12(ip);\n float b = hash12(ip + vec2(1.0, 0.0));\n float c = hash12(ip + vec2(0.0, 1.0));\n float d = hash12(ip + vec2(1.0, 1.0));\n \n vec2 t = smoothstep(0.0, 1.0, fp);\n return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n }\n\n float fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVE_COUNT; ++i) {\n value += amplitude * noise(p);\n p *= rotate2d(0.45);\n p *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n\n void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = fragCoord / iResolution.xy;\n uv = 2.0 * uv - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n uv.x += uXOffset;\n \n uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n \n float dist = abs(uv.x);\n vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n col = pow(col, vec3(1.0));\n float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n fragColor = vec4(col, a);\n }\n\n void main() {\n mainImage(gl_FragColor, gl_FragCoord.xy);\n }\n `;\n\n const compileShader = (source, type) => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n if (!vertexShader || !fragmentShader) return;\n\n const program = gl.createProgram();\n if (!program) return;\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n return;\n }\n gl.useProgram(program);\n\n const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n const vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const aPosition = gl.getAttribLocation(program, 'aPosition');\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n const uHueLocation = gl.getUniformLocation(program, 'uHue');\n const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n let animationFrameId;\n const startTime = performance.now();\n const render = () => {\n resizeCanvas();\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n const currentTime = performance.now();\n gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n gl.uniform1f(uHueLocation, hue);\n gl.uniform1f(uXOffsetLocation, xOffset);\n gl.uniform1f(uSpeedLocation, speed);\n gl.uniform1f(uIntensityLocation, intensity);\n gl.uniform1f(uSizeLocation, size);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n animationFrameId = requestAnimationFrame(render);\n };\n animationFrameId = requestAnimationFrame(render);\n\n return () => {\n cancelAnimationFrame(animationFrameId);\n window.removeEventListener('resize', resizeCanvas);\n };\n }, [hue, xOffset, speed, intensity, size]);\n\n return ;\n};\n\nexport default Lightning;\n" } ], "registryDependencies": [], diff --git a/public/r/Lightning-TS-CSS.json b/public/r/Lightning-TS-CSS.json index 009e38b5a..419c71326 100644 --- a/public/r/Lightning-TS-CSS.json +++ b/public/r/Lightning-TS-CSS.json @@ -13,7 +13,7 @@ { "type": "registry:component", "path": "Lightning/Lightning.tsx", - "content": "import React, { useRef, useEffect } from 'react';\nimport './Lightning.css';\n\ninterface LightningProps {\n hue?: number;\n xOffset?: number;\n speed?: number;\n intensity?: number;\n size?: number;\n}\n\nconst Lightning: React.FC = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const resizeCanvas = () => {\n canvas.width = canvas.clientWidth;\n canvas.height = canvas.clientHeight;\n };\n resizeCanvas();\n window.addEventListener('resize', resizeCanvas);\n\n const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n if (!gl) {\n console.error('WebGL not supported');\n return;\n }\n\n const vertexShaderSource = `\n attribute vec2 aPosition;\n void main() {\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 iResolution;\n uniform float iTime;\n uniform float uHue;\n uniform float uXOffset;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uSize;\n \n #define OCTAVE_COUNT 10\n\n vec3 hsv2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return c.z * mix(vec3(1.0), rgb, c.y);\n }\n\n float hash11(float p) {\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n }\n\n float hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n mat2 rotate2d(float theta) {\n float c = cos(theta);\n float s = sin(theta);\n return mat2(c, -s, s, c);\n }\n\n float noise(vec2 p) {\n vec2 ip = floor(p);\n vec2 fp = fract(p);\n float a = hash12(ip);\n float b = hash12(ip + vec2(1.0, 0.0));\n float c = hash12(ip + vec2(0.0, 1.0));\n float d = hash12(ip + vec2(1.0, 1.0));\n \n vec2 t = smoothstep(0.0, 1.0, fp);\n return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n }\n\n float fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVE_COUNT; ++i) {\n value += amplitude * noise(p);\n p *= rotate2d(0.45);\n p *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n\n void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = fragCoord / iResolution.xy;\n uv = 2.0 * uv - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n uv.x += uXOffset;\n \n uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n \n float dist = abs(uv.x);\n vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n col = pow(col, vec3(1.0));\n float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n fragColor = vec4(col, a);\n }\n\n void main() {\n mainImage(gl_FragColor, gl_FragCoord.xy);\n }\n `;\n\n const compileShader = (source: string, type: number): WebGLShader | null => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n if (!vertexShader || !fragmentShader) return;\n\n const program = gl.createProgram();\n if (!program) return;\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n return;\n }\n gl.useProgram(program);\n\n const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n const vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const aPosition = gl.getAttribLocation(program, 'aPosition');\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n const uHueLocation = gl.getUniformLocation(program, 'uHue');\n const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n const startTime = performance.now();\n const render = () => {\n resizeCanvas();\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n const currentTime = performance.now();\n gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n gl.uniform1f(uHueLocation, hue);\n gl.uniform1f(uXOffsetLocation, xOffset);\n gl.uniform1f(uSpeedLocation, speed);\n gl.uniform1f(uIntensityLocation, intensity);\n gl.uniform1f(uSizeLocation, size);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n requestAnimationFrame(render);\n };\n requestAnimationFrame(render);\n\n return () => {\n window.removeEventListener('resize', resizeCanvas);\n };\n }, [hue, xOffset, speed, intensity, size]);\n\n return ;\n};\n\nexport default Lightning;\n" + "content": "import React, { useRef, useEffect } from 'react';\nimport './Lightning.css';\n\ninterface LightningProps {\n hue?: number;\n xOffset?: number;\n speed?: number;\n intensity?: number;\n size?: number;\n}\n\nconst Lightning: React.FC = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const resizeCanvas = () => {\n canvas.width = canvas.clientWidth;\n canvas.height = canvas.clientHeight;\n };\n resizeCanvas();\n window.addEventListener('resize', resizeCanvas);\n\n const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n if (!gl) {\n console.error('WebGL not supported');\n return;\n }\n\n const vertexShaderSource = `\n attribute vec2 aPosition;\n void main() {\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 iResolution;\n uniform float iTime;\n uniform float uHue;\n uniform float uXOffset;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uSize;\n \n #define OCTAVE_COUNT 10\n\n vec3 hsv2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return c.z * mix(vec3(1.0), rgb, c.y);\n }\n\n float hash11(float p) {\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n }\n\n float hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n mat2 rotate2d(float theta) {\n float c = cos(theta);\n float s = sin(theta);\n return mat2(c, -s, s, c);\n }\n\n float noise(vec2 p) {\n vec2 ip = floor(p);\n vec2 fp = fract(p);\n float a = hash12(ip);\n float b = hash12(ip + vec2(1.0, 0.0));\n float c = hash12(ip + vec2(0.0, 1.0));\n float d = hash12(ip + vec2(1.0, 1.0));\n \n vec2 t = smoothstep(0.0, 1.0, fp);\n return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n }\n\n float fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVE_COUNT; ++i) {\n value += amplitude * noise(p);\n p *= rotate2d(0.45);\n p *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n\n void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = fragCoord / iResolution.xy;\n uv = 2.0 * uv - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n uv.x += uXOffset;\n \n uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n \n float dist = abs(uv.x);\n vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n col = pow(col, vec3(1.0));\n float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n fragColor = vec4(col, a);\n }\n\n void main() {\n mainImage(gl_FragColor, gl_FragCoord.xy);\n }\n `;\n\n const compileShader = (source: string, type: number): WebGLShader | null => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n if (!vertexShader || !fragmentShader) return;\n\n const program = gl.createProgram();\n if (!program) return;\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n return;\n }\n gl.useProgram(program);\n\n const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n const vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const aPosition = gl.getAttribLocation(program, 'aPosition');\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n const uHueLocation = gl.getUniformLocation(program, 'uHue');\n const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n let animationFrameId: number;\n const startTime = performance.now();\n const render = () => {\n resizeCanvas();\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n const currentTime = performance.now();\n gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n gl.uniform1f(uHueLocation, hue);\n gl.uniform1f(uXOffsetLocation, xOffset);\n gl.uniform1f(uSpeedLocation, speed);\n gl.uniform1f(uIntensityLocation, intensity);\n gl.uniform1f(uSizeLocation, size);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n animationFrameId = requestAnimationFrame(render);\n };\n animationFrameId = requestAnimationFrame(render);\n\n return () => {\n cancelAnimationFrame(animationFrameId);\n window.removeEventListener('resize', resizeCanvas);\n };\n }, [hue, xOffset, speed, intensity, size]);\n\n return ;\n};\n\nexport default Lightning;\n" } ], "registryDependencies": [], diff --git a/public/r/Lightning-TS-TW.json b/public/r/Lightning-TS-TW.json index 91e58d45f..9937cec64 100644 --- a/public/r/Lightning-TS-TW.json +++ b/public/r/Lightning-TS-TW.json @@ -8,7 +8,7 @@ { "type": "registry:component", "path": "Lightning/Lightning.tsx", - "content": "import React, { useRef, useEffect } from 'react';\n\ninterface LightningProps {\n hue?: number;\n xOffset?: number;\n speed?: number;\n intensity?: number;\n size?: number;\n}\n\nconst Lightning: React.FC = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const resizeCanvas = () => {\n canvas.width = canvas.clientWidth;\n canvas.height = canvas.clientHeight;\n };\n resizeCanvas();\n window.addEventListener('resize', resizeCanvas);\n\n const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n if (!gl) {\n console.error('WebGL not supported');\n return;\n }\n\n const vertexShaderSource = `\n attribute vec2 aPosition;\n void main() {\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 iResolution;\n uniform float iTime;\n uniform float uHue;\n uniform float uXOffset;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uSize;\n \n #define OCTAVE_COUNT 10\n\n vec3 hsv2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return c.z * mix(vec3(1.0), rgb, c.y);\n }\n\n float hash11(float p) {\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n }\n\n float hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n mat2 rotate2d(float theta) {\n float c = cos(theta);\n float s = sin(theta);\n return mat2(c, -s, s, c);\n }\n\n float noise(vec2 p) {\n vec2 ip = floor(p);\n vec2 fp = fract(p);\n float a = hash12(ip);\n float b = hash12(ip + vec2(1.0, 0.0));\n float c = hash12(ip + vec2(0.0, 1.0));\n float d = hash12(ip + vec2(1.0, 1.0));\n \n vec2 t = smoothstep(0.0, 1.0, fp);\n return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n }\n\n float fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVE_COUNT; ++i) {\n value += amplitude * noise(p);\n p *= rotate2d(0.45);\n p *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n\n void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = fragCoord / iResolution.xy;\n uv = 2.0 * uv - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n uv.x += uXOffset;\n \n uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n \n float dist = abs(uv.x);\n vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n col = pow(col, vec3(1.0));\n float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n fragColor = vec4(col, a);\n }\n\n void main() {\n mainImage(gl_FragColor, gl_FragCoord.xy);\n }\n `;\n\n const compileShader = (source: string, type: number): WebGLShader | null => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n if (!vertexShader || !fragmentShader) return;\n\n const program = gl.createProgram();\n if (!program) return;\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n return;\n }\n gl.useProgram(program);\n\n const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n const vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const aPosition = gl.getAttribLocation(program, 'aPosition');\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n const uHueLocation = gl.getUniformLocation(program, 'uHue');\n const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n const startTime = performance.now();\n const render = () => {\n resizeCanvas();\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n const currentTime = performance.now();\n gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n gl.uniform1f(uHueLocation, hue);\n gl.uniform1f(uXOffsetLocation, xOffset);\n gl.uniform1f(uSpeedLocation, speed);\n gl.uniform1f(uIntensityLocation, intensity);\n gl.uniform1f(uSizeLocation, size);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n requestAnimationFrame(render);\n };\n requestAnimationFrame(render);\n\n return () => {\n window.removeEventListener('resize', resizeCanvas);\n };\n }, [hue, xOffset, speed, intensity, size]);\n\n return ;\n};\n\nexport default Lightning;\n" + "content": "import React, { useRef, useEffect } from 'react';\n\ninterface LightningProps {\n hue?: number;\n xOffset?: number;\n speed?: number;\n intensity?: number;\n size?: number;\n}\n\nconst Lightning: React.FC = ({ hue = 230, xOffset = 0, speed = 1, intensity = 1, size = 1 }) => {\n const canvasRef = useRef(null);\n\n useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n const resizeCanvas = () => {\n canvas.width = canvas.clientWidth;\n canvas.height = canvas.clientHeight;\n };\n resizeCanvas();\n window.addEventListener('resize', resizeCanvas);\n\n const gl = canvas.getContext('webgl', { alpha: true, premultipliedAlpha: false });\n if (!gl) {\n console.error('WebGL not supported');\n return;\n }\n\n const vertexShaderSource = `\n attribute vec2 aPosition;\n void main() {\n gl_Position = vec4(aPosition, 0.0, 1.0);\n }\n `;\n\n const fragmentShaderSource = `\n precision mediump float;\n uniform vec2 iResolution;\n uniform float iTime;\n uniform float uHue;\n uniform float uXOffset;\n uniform float uSpeed;\n uniform float uIntensity;\n uniform float uSize;\n \n #define OCTAVE_COUNT 10\n\n vec3 hsv2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0,4.0,2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);\n return c.z * mix(vec3(1.0), rgb, c.y);\n }\n\n float hash11(float p) {\n p = fract(p * .1031);\n p *= p + 33.33;\n p *= p + p;\n return fract(p);\n }\n\n float hash12(vec2 p) {\n vec3 p3 = fract(vec3(p.xyx) * .1031);\n p3 += dot(p3, p3.yzx + 33.33);\n return fract((p3.x + p3.y) * p3.z);\n }\n\n mat2 rotate2d(float theta) {\n float c = cos(theta);\n float s = sin(theta);\n return mat2(c, -s, s, c);\n }\n\n float noise(vec2 p) {\n vec2 ip = floor(p);\n vec2 fp = fract(p);\n float a = hash12(ip);\n float b = hash12(ip + vec2(1.0, 0.0));\n float c = hash12(ip + vec2(0.0, 1.0));\n float d = hash12(ip + vec2(1.0, 1.0));\n \n vec2 t = smoothstep(0.0, 1.0, fp);\n return mix(mix(a, b, t.x), mix(c, d, t.x), t.y);\n }\n\n float fbm(vec2 p) {\n float value = 0.0;\n float amplitude = 0.5;\n for (int i = 0; i < OCTAVE_COUNT; ++i) {\n value += amplitude * noise(p);\n p *= rotate2d(0.45);\n p *= 2.0;\n amplitude *= 0.5;\n }\n return value;\n }\n\n void mainImage( out vec4 fragColor, in vec2 fragCoord ) {\n vec2 uv = fragCoord / iResolution.xy;\n uv = 2.0 * uv - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n uv.x += uXOffset;\n \n uv += 2.0 * fbm(uv * uSize + 0.8 * iTime * uSpeed) - 1.0;\n \n float dist = abs(uv.x);\n vec3 baseColor = hsv2rgb(vec3(uHue / 360.0, 0.7, 0.8));\n vec3 col = baseColor * pow(mix(0.0, 0.07, hash11(iTime * uSpeed)) / dist, 1.0) * uIntensity;\n col = pow(col, vec3(1.0));\n float a = clamp(max(col.r, max(col.g, col.b)), 0.0, 1.0);\n fragColor = vec4(col, a);\n }\n\n void main() {\n mainImage(gl_FragColor, gl_FragCoord.xy);\n }\n `;\n\n const compileShader = (source: string, type: number): WebGLShader | null => {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n console.error('Shader compile error:', gl.getShaderInfoLog(shader));\n gl.deleteShader(shader);\n return null;\n }\n return shader;\n };\n\n const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);\n const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);\n if (!vertexShader || !fragmentShader) return;\n\n const program = gl.createProgram();\n if (!program) return;\n gl.attachShader(program, vertexShader);\n gl.attachShader(program, fragmentShader);\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n console.error('Program linking error:', gl.getProgramInfoLog(program));\n return;\n }\n gl.useProgram(program);\n\n const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]);\n const vertexBuffer = gl.createBuffer();\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);\n\n const aPosition = gl.getAttribLocation(program, 'aPosition');\n gl.enableVertexAttribArray(aPosition);\n gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);\n\n const iResolutionLocation = gl.getUniformLocation(program, 'iResolution');\n const iTimeLocation = gl.getUniformLocation(program, 'iTime');\n const uHueLocation = gl.getUniformLocation(program, 'uHue');\n const uXOffsetLocation = gl.getUniformLocation(program, 'uXOffset');\n const uSpeedLocation = gl.getUniformLocation(program, 'uSpeed');\n const uIntensityLocation = gl.getUniformLocation(program, 'uIntensity');\n const uSizeLocation = gl.getUniformLocation(program, 'uSize');\n\n let animationFrameId: number;\n const startTime = performance.now();\n const render = () => {\n resizeCanvas();\n gl.viewport(0, 0, canvas.width, canvas.height);\n gl.uniform2f(iResolutionLocation, canvas.width, canvas.height);\n const currentTime = performance.now();\n gl.uniform1f(iTimeLocation, (currentTime - startTime) / 1000.0);\n gl.uniform1f(uHueLocation, hue);\n gl.uniform1f(uXOffsetLocation, xOffset);\n gl.uniform1f(uSpeedLocation, speed);\n gl.uniform1f(uIntensityLocation, intensity);\n gl.uniform1f(uSizeLocation, size);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n animationFrameId = requestAnimationFrame(render);\n };\n animationFrameId = requestAnimationFrame(render);\n\n return () => {\n cancelAnimationFrame(animationFrameId);\n window.removeEventListener('resize', resizeCanvas);\n };\n }, [hue, xOffset, speed, intensity, size]);\n\n return ;\n};\n\nexport default Lightning;\n" } ], "registryDependencies": [], diff --git a/public/r/RippleGrid-JS-CSS.json b/public/r/RippleGrid-JS-CSS.json index e46dc40f8..119dde45f 100644 --- a/public/r/RippleGrid-JS-CSS.json +++ b/public/r/RippleGrid-JS-CSS.json @@ -13,7 +13,7 @@ { "type": "registry:component", "path": "RippleGrid/RippleGrid.jsx", - "content": "import { useRef, useEffect } from 'react';\nimport { Renderer, Program, Triangle, Mesh } from 'ogl';\nimport './RippleGrid.css';\n\nconst RippleGrid = ({\n enableRainbow = false,\n gridColor = '#ffffff',\n rippleIntensity = 0.05,\n gridSize = 10.0,\n gridThickness = 15.0,\n fadeDistance = 1.5,\n vignetteStrength = 2.0,\n glowIntensity = 0.1,\n opacity = 1.0,\n gridRotation = 0,\n mouseInteraction = true,\n mouseInteractionRadius = 1\n}) => {\n const containerRef = useRef(null);\n const mousePositionRef = useRef({ x: 0.5, y: 0.5 });\n const targetMouseRef = useRef({ x: 0.5, y: 0.5 });\n const mouseInfluenceRef = useRef(0);\n const uniformsRef = useRef(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const hexToRgb = hex => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n const renderer = new Renderer({\n dpr: Math.min(window.devicePixelRatio, 2),\n alpha: true\n });\n const gl = renderer.gl;\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.canvas.style.width = '100%';\n gl.canvas.style.height = '100%';\n containerRef.current.appendChild(gl.canvas);\n\n const vert = `\nattribute vec2 position;\nvarying vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n const frag = `precision highp float;\nuniform float iTime;\nuniform vec2 iResolution;\nuniform bool enableRainbow;\nuniform vec3 gridColor;\nuniform float rippleIntensity;\nuniform float gridSize;\nuniform float gridThickness;\nuniform float fadeDistance;\nuniform float vignetteStrength;\nuniform float glowIntensity;\nuniform float opacity;\nuniform float gridRotation;\nuniform bool mouseInteraction;\nuniform vec2 mousePosition;\nuniform float mouseInfluence;\nuniform float mouseInteractionRadius;\nvarying vec2 vUv;\n\nfloat pi = 3.141592;\n\nmat2 rotate(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec2 uv = vUv * 2.0 - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n\n if (gridRotation != 0.0) {\n uv = rotate(gridRotation * pi / 180.0) * uv;\n }\n\n float dist = length(uv);\n float func = sin(pi * (iTime - dist));\n vec2 rippleUv = uv + uv * func * rippleIntensity;\n\n if (mouseInteraction && mouseInfluence > 0.0) {\n vec2 mouseUv = (mousePosition * 2.0 - 1.0);\n mouseUv.x *= iResolution.x / iResolution.y;\n float mouseDist = length(uv - mouseUv);\n \n float influence = mouseInfluence * exp(-mouseDist * mouseDist / (mouseInteractionRadius * mouseInteractionRadius));\n \n float mouseWave = sin(pi * (iTime * 2.0 - mouseDist * 3.0)) * influence;\n rippleUv += normalize(uv - mouseUv) * mouseWave * rippleIntensity * 0.3;\n }\n\n vec2 a = sin(gridSize * 0.5 * pi * rippleUv - pi / 2.0);\n vec2 b = abs(a);\n\n float aaWidth = 0.5;\n vec2 smoothB = vec2(\n smoothstep(0.0, aaWidth, b.x),\n smoothstep(0.0, aaWidth, b.y)\n );\n\n vec3 color = vec3(0.0);\n color += exp(-gridThickness * smoothB.x * (0.8 + 0.5 * sin(pi * iTime)));\n color += exp(-gridThickness * smoothB.y);\n color += 0.5 * exp(-(gridThickness / 4.0) * sin(smoothB.x));\n color += 0.5 * exp(-(gridThickness / 3.0) * smoothB.y);\n\n if (glowIntensity > 0.0) {\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.x);\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.y);\n }\n\n float ddd = exp(-2.0 * clamp(pow(dist, fadeDistance), 0.0, 1.0));\n \n vec2 vignetteCoords = vUv - 0.5;\n float vignetteDistance = length(vignetteCoords);\n float vignette = 1.0 - pow(vignetteDistance * 2.0, vignetteStrength);\n vignette = clamp(vignette, 0.0, 1.0);\n \n vec3 t;\n if (enableRainbow) {\n t = vec3(\n uv.x * 0.5 + 0.5 * sin(iTime),\n uv.y * 0.5 + 0.5 * cos(iTime),\n pow(cos(iTime), 4.0)\n ) + 0.5;\n } else {\n t = gridColor;\n }\n\n float finalFade = ddd * vignette;\n float alpha = length(color) * finalFade * opacity;\n gl_FragColor = vec4(color * t * finalFade * opacity, alpha);\n}`;\n\n const uniforms = {\n iTime: { value: 0 },\n iResolution: { value: [1, 1] },\n enableRainbow: { value: enableRainbow },\n gridColor: { value: hexToRgb(gridColor) },\n rippleIntensity: { value: rippleIntensity },\n gridSize: { value: gridSize },\n gridThickness: { value: gridThickness },\n fadeDistance: { value: fadeDistance },\n vignetteStrength: { value: vignetteStrength },\n glowIntensity: { value: glowIntensity },\n opacity: { value: opacity },\n gridRotation: { value: gridRotation },\n mouseInteraction: { value: mouseInteraction },\n mousePosition: { value: [0.5, 0.5] },\n mouseInfluence: { value: 0 },\n mouseInteractionRadius: { value: mouseInteractionRadius }\n };\n\n uniformsRef.current = uniforms;\n\n const geometry = new Triangle(gl);\n const program = new Program(gl, { vertex: vert, fragment: frag, uniforms });\n const mesh = new Mesh(gl, { geometry, program });\n\n const resize = () => {\n const { clientWidth: w, clientHeight: h } = containerRef.current;\n renderer.setSize(w, h);\n uniforms.iResolution.value = [w, h];\n };\n\n const handleMouseMove = e => {\n if (!mouseInteraction || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = 1.0 - (e.clientY - rect.top) / rect.height; // Flip Y coordinate\n targetMouseRef.current = { x, y };\n };\n\n const handleMouseEnter = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 1.0;\n };\n\n const handleMouseLeave = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 0.0;\n };\n\n window.addEventListener('resize', resize);\n if (mouseInteraction) {\n containerRef.current.addEventListener('mousemove', handleMouseMove);\n containerRef.current.addEventListener('mouseenter', handleMouseEnter);\n containerRef.current.addEventListener('mouseleave', handleMouseLeave);\n }\n resize();\n\n const render = t => {\n uniforms.iTime.value = t * 0.001;\n\n const lerpFactor = 0.1;\n mousePositionRef.current.x += (targetMouseRef.current.x - mousePositionRef.current.x) * lerpFactor;\n mousePositionRef.current.y += (targetMouseRef.current.y - mousePositionRef.current.y) * lerpFactor;\n\n const currentInfluence = uniforms.mouseInfluence.value;\n const targetInfluence = mouseInfluenceRef.current;\n uniforms.mouseInfluence.value += (targetInfluence - currentInfluence) * 0.05;\n\n uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y];\n\n renderer.render({ scene: mesh });\n requestAnimationFrame(render);\n };\n\n requestAnimationFrame(render);\n\n const container = containerRef.current;\n return () => {\n window.removeEventListener('resize', resize);\n if (mouseInteraction && container) {\n container.removeEventListener('mousemove', handleMouseMove);\n container.removeEventListener('mouseenter', handleMouseEnter);\n container.removeEventListener('mouseleave', handleMouseLeave);\n }\n renderer.gl.getExtension('WEBGL_lose_context')?.loseContext();\n container?.removeChild(gl.canvas);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (!uniformsRef.current) return;\n\n const hexToRgb = hex => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n uniformsRef.current.enableRainbow.value = enableRainbow;\n uniformsRef.current.gridColor.value = hexToRgb(gridColor);\n uniformsRef.current.rippleIntensity.value = rippleIntensity;\n uniformsRef.current.gridSize.value = gridSize;\n uniformsRef.current.gridThickness.value = gridThickness;\n uniformsRef.current.fadeDistance.value = fadeDistance;\n uniformsRef.current.vignetteStrength.value = vignetteStrength;\n uniformsRef.current.glowIntensity.value = glowIntensity;\n uniformsRef.current.opacity.value = opacity;\n uniformsRef.current.gridRotation.value = gridRotation;\n uniformsRef.current.mouseInteraction.value = mouseInteraction;\n uniformsRef.current.mouseInteractionRadius.value = mouseInteractionRadius;\n }, [\n enableRainbow,\n gridColor,\n rippleIntensity,\n gridSize,\n gridThickness,\n fadeDistance,\n vignetteStrength,\n glowIntensity,\n opacity,\n gridRotation,\n mouseInteraction,\n mouseInteractionRadius\n ]);\n\n return
;\n};\n\nexport default RippleGrid;\n" + "content": "import { useRef, useEffect } from 'react';\nimport { Renderer, Program, Triangle, Mesh } from 'ogl';\nimport './RippleGrid.css';\n\nconst RippleGrid = ({\n enableRainbow = false,\n gridColor = '#ffffff',\n rippleIntensity = 0.05,\n gridSize = 10.0,\n gridThickness = 15.0,\n fadeDistance = 1.5,\n vignetteStrength = 2.0,\n glowIntensity = 0.1,\n opacity = 1.0,\n gridRotation = 0,\n mouseInteraction = true,\n mouseInteractionRadius = 1\n}) => {\n const containerRef = useRef(null);\n const mousePositionRef = useRef({ x: 0.5, y: 0.5 });\n const targetMouseRef = useRef({ x: 0.5, y: 0.5 });\n const mouseInfluenceRef = useRef(0);\n const uniformsRef = useRef(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const hexToRgb = hex => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n const renderer = new Renderer({\n dpr: Math.min(window.devicePixelRatio, 2),\n alpha: true\n });\n const gl = renderer.gl;\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.canvas.style.width = '100%';\n gl.canvas.style.height = '100%';\n containerRef.current.appendChild(gl.canvas);\n\n const vert = `\nattribute vec2 position;\nvarying vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n const frag = `precision highp float;\nuniform float iTime;\nuniform vec2 iResolution;\nuniform bool enableRainbow;\nuniform vec3 gridColor;\nuniform float rippleIntensity;\nuniform float gridSize;\nuniform float gridThickness;\nuniform float fadeDistance;\nuniform float vignetteStrength;\nuniform float glowIntensity;\nuniform float opacity;\nuniform float gridRotation;\nuniform bool mouseInteraction;\nuniform vec2 mousePosition;\nuniform float mouseInfluence;\nuniform float mouseInteractionRadius;\nvarying vec2 vUv;\n\nfloat pi = 3.141592;\n\nmat2 rotate(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec2 uv = vUv * 2.0 - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n\n if (gridRotation != 0.0) {\n uv = rotate(gridRotation * pi / 180.0) * uv;\n }\n\n float dist = length(uv);\n float func = sin(pi * (iTime - dist));\n vec2 rippleUv = uv + uv * func * rippleIntensity;\n\n if (mouseInteraction && mouseInfluence > 0.0) {\n vec2 mouseUv = (mousePosition * 2.0 - 1.0);\n mouseUv.x *= iResolution.x / iResolution.y;\n float mouseDist = length(uv - mouseUv);\n \n float influence = mouseInfluence * exp(-mouseDist * mouseDist / (mouseInteractionRadius * mouseInteractionRadius));\n \n float mouseWave = sin(pi * (iTime * 2.0 - mouseDist * 3.0)) * influence;\n rippleUv += normalize(uv - mouseUv) * mouseWave * rippleIntensity * 0.3;\n }\n\n vec2 a = sin(gridSize * 0.5 * pi * rippleUv - pi / 2.0);\n vec2 b = abs(a);\n\n float aaWidth = 0.5;\n vec2 smoothB = vec2(\n smoothstep(0.0, aaWidth, b.x),\n smoothstep(0.0, aaWidth, b.y)\n );\n\n vec3 color = vec3(0.0);\n color += exp(-gridThickness * smoothB.x * (0.8 + 0.5 * sin(pi * iTime)));\n color += exp(-gridThickness * smoothB.y);\n color += 0.5 * exp(-(gridThickness / 4.0) * sin(smoothB.x));\n color += 0.5 * exp(-(gridThickness / 3.0) * smoothB.y);\n\n if (glowIntensity > 0.0) {\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.x);\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.y);\n }\n\n float ddd = exp(-2.0 * clamp(pow(dist, fadeDistance), 0.0, 1.0));\n \n vec2 vignetteCoords = vUv - 0.5;\n float vignetteDistance = length(vignetteCoords);\n float vignette = 1.0 - pow(vignetteDistance * 2.0, vignetteStrength);\n vignette = clamp(vignette, 0.0, 1.0);\n \n vec3 t;\n if (enableRainbow) {\n t = vec3(\n uv.x * 0.5 + 0.5 * sin(iTime),\n uv.y * 0.5 + 0.5 * cos(iTime),\n pow(cos(iTime), 4.0)\n ) + 0.5;\n } else {\n t = gridColor;\n }\n\n float finalFade = ddd * vignette;\n float alpha = length(color) * finalFade * opacity;\n gl_FragColor = vec4(color * t * finalFade * opacity, alpha);\n}`;\n\n const uniforms = {\n iTime: { value: 0 },\n iResolution: { value: [1, 1] },\n enableRainbow: { value: enableRainbow },\n gridColor: { value: hexToRgb(gridColor) },\n rippleIntensity: { value: rippleIntensity },\n gridSize: { value: gridSize },\n gridThickness: { value: gridThickness },\n fadeDistance: { value: fadeDistance },\n vignetteStrength: { value: vignetteStrength },\n glowIntensity: { value: glowIntensity },\n opacity: { value: opacity },\n gridRotation: { value: gridRotation },\n mouseInteraction: { value: mouseInteraction },\n mousePosition: { value: [0.5, 0.5] },\n mouseInfluence: { value: 0 },\n mouseInteractionRadius: { value: mouseInteractionRadius }\n };\n\n uniformsRef.current = uniforms;\n\n const geometry = new Triangle(gl);\n const program = new Program(gl, { vertex: vert, fragment: frag, uniforms });\n const mesh = new Mesh(gl, { geometry, program });\n\n const resize = () => {\n const { clientWidth: w, clientHeight: h } = containerRef.current;\n renderer.setSize(w, h);\n uniforms.iResolution.value = [w, h];\n };\n\n const handleMouseMove = e => {\n if (!mouseInteraction || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = 1.0 - (e.clientY - rect.top) / rect.height; // Flip Y coordinate\n targetMouseRef.current = { x, y };\n };\n\n const handleMouseEnter = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 1.0;\n };\n\n const handleMouseLeave = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 0.0;\n };\n\n window.addEventListener('resize', resize);\n if (mouseInteraction) {\n containerRef.current.addEventListener('mousemove', handleMouseMove);\n containerRef.current.addEventListener('mouseenter', handleMouseEnter);\n containerRef.current.addEventListener('mouseleave', handleMouseLeave);\n }\n resize();\n\n let animationFrameId;\n const render = t => {\n uniforms.iTime.value = t * 0.001;\n\n const lerpFactor = 0.1;\n mousePositionRef.current.x += (targetMouseRef.current.x - mousePositionRef.current.x) * lerpFactor;\n mousePositionRef.current.y += (targetMouseRef.current.y - mousePositionRef.current.y) * lerpFactor;\n\n const currentInfluence = uniforms.mouseInfluence.value;\n const targetInfluence = mouseInfluenceRef.current;\n uniforms.mouseInfluence.value += (targetInfluence - currentInfluence) * 0.05;\n\n uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y];\n\n renderer.render({ scene: mesh });\n animationFrameId = requestAnimationFrame(render);\n };\n\n animationFrameId = requestAnimationFrame(render);\n\n const container = containerRef.current;\n return () => {\n cancelAnimationFrame(animationFrameId);\n window.removeEventListener('resize', resize);\n if (mouseInteraction && container) {\n container.removeEventListener('mousemove', handleMouseMove);\n container.removeEventListener('mouseenter', handleMouseEnter);\n container.removeEventListener('mouseleave', handleMouseLeave);\n }\n renderer.gl.getExtension('WEBGL_lose_context')?.loseContext();\n container?.removeChild(gl.canvas);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (!uniformsRef.current) return;\n\n const hexToRgb = hex => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n uniformsRef.current.enableRainbow.value = enableRainbow;\n uniformsRef.current.gridColor.value = hexToRgb(gridColor);\n uniformsRef.current.rippleIntensity.value = rippleIntensity;\n uniformsRef.current.gridSize.value = gridSize;\n uniformsRef.current.gridThickness.value = gridThickness;\n uniformsRef.current.fadeDistance.value = fadeDistance;\n uniformsRef.current.vignetteStrength.value = vignetteStrength;\n uniformsRef.current.glowIntensity.value = glowIntensity;\n uniformsRef.current.opacity.value = opacity;\n uniformsRef.current.gridRotation.value = gridRotation;\n uniformsRef.current.mouseInteraction.value = mouseInteraction;\n uniformsRef.current.mouseInteractionRadius.value = mouseInteractionRadius;\n }, [\n enableRainbow,\n gridColor,\n rippleIntensity,\n gridSize,\n gridThickness,\n fadeDistance,\n vignetteStrength,\n glowIntensity,\n opacity,\n gridRotation,\n mouseInteraction,\n mouseInteractionRadius\n ]);\n\n return
;\n};\n\nexport default RippleGrid;\n" } ], "registryDependencies": [], diff --git a/public/r/RippleGrid-JS-TW.json b/public/r/RippleGrid-JS-TW.json index 853b0b709..894e04b7b 100644 --- a/public/r/RippleGrid-JS-TW.json +++ b/public/r/RippleGrid-JS-TW.json @@ -8,7 +8,7 @@ { "type": "registry:component", "path": "RippleGrid/RippleGrid.jsx", - "content": "import { useRef, useEffect } from 'react';\nimport { Renderer, Program, Triangle, Mesh } from 'ogl';\n\nconst RippleGrid = ({\n enableRainbow = false,\n gridColor = '#ffffff',\n rippleIntensity = 0.05,\n gridSize = 10.0,\n gridThickness = 15.0,\n fadeDistance = 1.5,\n vignetteStrength = 2.0,\n glowIntensity = 0.1,\n opacity = 1.0,\n gridRotation = 0,\n mouseInteraction = true,\n mouseInteractionRadius = 1\n}) => {\n const containerRef = useRef(null);\n const mousePositionRef = useRef({ x: 0.5, y: 0.5 });\n const targetMouseRef = useRef({ x: 0.5, y: 0.5 });\n const mouseInfluenceRef = useRef(0);\n const uniformsRef = useRef(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const hexToRgb = hex => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n const renderer = new Renderer({\n dpr: Math.min(window.devicePixelRatio, 2),\n alpha: true\n });\n const gl = renderer.gl;\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.canvas.style.width = '100%';\n gl.canvas.style.height = '100%';\n containerRef.current.appendChild(gl.canvas);\n\n const vert = `\nattribute vec2 position;\nvarying vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n const frag = `precision highp float;\nuniform float iTime;\nuniform vec2 iResolution;\nuniform bool enableRainbow;\nuniform vec3 gridColor;\nuniform float rippleIntensity;\nuniform float gridSize;\nuniform float gridThickness;\nuniform float fadeDistance;\nuniform float vignetteStrength;\nuniform float glowIntensity;\nuniform float opacity;\nuniform float gridRotation;\nuniform bool mouseInteraction;\nuniform vec2 mousePosition;\nuniform float mouseInfluence;\nuniform float mouseInteractionRadius;\nvarying vec2 vUv;\n\nfloat pi = 3.141592;\n\nmat2 rotate(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec2 uv = vUv * 2.0 - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n\n if (gridRotation != 0.0) {\n uv = rotate(gridRotation * pi / 180.0) * uv;\n }\n\n float dist = length(uv);\n float func = sin(pi * (iTime - dist));\n vec2 rippleUv = uv + uv * func * rippleIntensity;\n\n if (mouseInteraction && mouseInfluence > 0.0) {\n vec2 mouseUv = (mousePosition * 2.0 - 1.0);\n mouseUv.x *= iResolution.x / iResolution.y;\n float mouseDist = length(uv - mouseUv);\n \n float influence = mouseInfluence * exp(-mouseDist * mouseDist / (mouseInteractionRadius * mouseInteractionRadius));\n \n float mouseWave = sin(pi * (iTime * 2.0 - mouseDist * 3.0)) * influence;\n rippleUv += normalize(uv - mouseUv) * mouseWave * rippleIntensity * 0.3;\n }\n\n vec2 a = sin(gridSize * 0.5 * pi * rippleUv - pi / 2.0);\n vec2 b = abs(a);\n\n float aaWidth = 0.5;\n vec2 smoothB = vec2(\n smoothstep(0.0, aaWidth, b.x),\n smoothstep(0.0, aaWidth, b.y)\n );\n\n vec3 color = vec3(0.0);\n color += exp(-gridThickness * smoothB.x * (0.8 + 0.5 * sin(pi * iTime)));\n color += exp(-gridThickness * smoothB.y);\n color += 0.5 * exp(-(gridThickness / 4.0) * sin(smoothB.x));\n color += 0.5 * exp(-(gridThickness / 3.0) * smoothB.y);\n\n if (glowIntensity > 0.0) {\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.x);\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.y);\n }\n\n float ddd = exp(-2.0 * clamp(pow(dist, fadeDistance), 0.0, 1.0));\n \n vec2 vignetteCoords = vUv - 0.5;\n float vignetteDistance = length(vignetteCoords);\n float vignette = 1.0 - pow(vignetteDistance * 2.0, vignetteStrength);\n vignette = clamp(vignette, 0.0, 1.0);\n \n vec3 t;\n if (enableRainbow) {\n t = vec3(\n uv.x * 0.5 + 0.5 * sin(iTime),\n uv.y * 0.5 + 0.5 * cos(iTime),\n pow(cos(iTime), 4.0)\n ) + 0.5;\n } else {\n t = gridColor;\n }\n\n float finalFade = ddd * vignette;\n float alpha = length(color) * finalFade * opacity;\n gl_FragColor = vec4(color * t * finalFade * opacity, alpha);\n}`;\n\n const uniforms = {\n iTime: { value: 0 },\n iResolution: { value: [1, 1] },\n enableRainbow: { value: enableRainbow },\n gridColor: { value: hexToRgb(gridColor) },\n rippleIntensity: { value: rippleIntensity },\n gridSize: { value: gridSize },\n gridThickness: { value: gridThickness },\n fadeDistance: { value: fadeDistance },\n vignetteStrength: { value: vignetteStrength },\n glowIntensity: { value: glowIntensity },\n opacity: { value: opacity },\n gridRotation: { value: gridRotation },\n mouseInteraction: { value: mouseInteraction },\n mousePosition: { value: [0.5, 0.5] },\n mouseInfluence: { value: 0 },\n mouseInteractionRadius: { value: mouseInteractionRadius }\n };\n\n uniformsRef.current = uniforms;\n\n const geometry = new Triangle(gl);\n const program = new Program(gl, { vertex: vert, fragment: frag, uniforms });\n const mesh = new Mesh(gl, { geometry, program });\n\n const resize = () => {\n const { clientWidth: w, clientHeight: h } = containerRef.current;\n renderer.setSize(w, h);\n uniforms.iResolution.value = [w, h];\n };\n\n const handleMouseMove = e => {\n if (!mouseInteraction || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = 1.0 - (e.clientY - rect.top) / rect.height; // Flip Y coordinate\n targetMouseRef.current = { x, y };\n };\n\n const handleMouseEnter = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 1.0;\n };\n\n const handleMouseLeave = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 0.0;\n };\n\n window.addEventListener('resize', resize);\n if (mouseInteraction) {\n containerRef.current.addEventListener('mousemove', handleMouseMove);\n containerRef.current.addEventListener('mouseenter', handleMouseEnter);\n containerRef.current.addEventListener('mouseleave', handleMouseLeave);\n }\n resize();\n\n const render = t => {\n uniforms.iTime.value = t * 0.001;\n\n const lerpFactor = 0.1;\n mousePositionRef.current.x += (targetMouseRef.current.x - mousePositionRef.current.x) * lerpFactor;\n mousePositionRef.current.y += (targetMouseRef.current.y - mousePositionRef.current.y) * lerpFactor;\n\n const currentInfluence = uniforms.mouseInfluence.value;\n const targetInfluence = mouseInfluenceRef.current;\n uniforms.mouseInfluence.value += (targetInfluence - currentInfluence) * 0.05;\n\n uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y];\n\n renderer.render({ scene: mesh });\n requestAnimationFrame(render);\n };\n\n requestAnimationFrame(render);\n\n const container = containerRef.current;\n return () => {\n window.removeEventListener('resize', resize);\n if (mouseInteraction && container) {\n container.removeEventListener('mousemove', handleMouseMove);\n container.removeEventListener('mouseenter', handleMouseEnter);\n container.removeEventListener('mouseleave', handleMouseLeave);\n }\n renderer.gl.getExtension('WEBGL_lose_context')?.loseContext();\n container?.removeChild(gl.canvas);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (!uniformsRef.current) return;\n\n const hexToRgb = hex => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n uniformsRef.current.enableRainbow.value = enableRainbow;\n uniformsRef.current.gridColor.value = hexToRgb(gridColor);\n uniformsRef.current.rippleIntensity.value = rippleIntensity;\n uniformsRef.current.gridSize.value = gridSize;\n uniformsRef.current.gridThickness.value = gridThickness;\n uniformsRef.current.fadeDistance.value = fadeDistance;\n uniformsRef.current.vignetteStrength.value = vignetteStrength;\n uniformsRef.current.glowIntensity.value = glowIntensity;\n uniformsRef.current.opacity.value = opacity;\n uniformsRef.current.gridRotation.value = gridRotation;\n uniformsRef.current.mouseInteraction.value = mouseInteraction;\n uniformsRef.current.mouseInteractionRadius.value = mouseInteractionRadius;\n }, [\n enableRainbow,\n gridColor,\n rippleIntensity,\n gridSize,\n gridThickness,\n fadeDistance,\n vignetteStrength,\n glowIntensity,\n opacity,\n gridRotation,\n mouseInteraction,\n mouseInteractionRadius\n ]);\n\n return
;\n};\n\nexport default RippleGrid;\n" + "content": "import { useRef, useEffect } from 'react';\nimport { Renderer, Program, Triangle, Mesh } from 'ogl';\n\nconst RippleGrid = ({\n enableRainbow = false,\n gridColor = '#ffffff',\n rippleIntensity = 0.05,\n gridSize = 10.0,\n gridThickness = 15.0,\n fadeDistance = 1.5,\n vignetteStrength = 2.0,\n glowIntensity = 0.1,\n opacity = 1.0,\n gridRotation = 0,\n mouseInteraction = true,\n mouseInteractionRadius = 1\n}) => {\n const containerRef = useRef(null);\n const mousePositionRef = useRef({ x: 0.5, y: 0.5 });\n const targetMouseRef = useRef({ x: 0.5, y: 0.5 });\n const mouseInfluenceRef = useRef(0);\n const uniformsRef = useRef(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const hexToRgb = hex => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n const renderer = new Renderer({\n dpr: Math.min(window.devicePixelRatio, 2),\n alpha: true\n });\n const gl = renderer.gl;\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.canvas.style.width = '100%';\n gl.canvas.style.height = '100%';\n containerRef.current.appendChild(gl.canvas);\n\n const vert = `\nattribute vec2 position;\nvarying vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n const frag = `precision highp float;\nuniform float iTime;\nuniform vec2 iResolution;\nuniform bool enableRainbow;\nuniform vec3 gridColor;\nuniform float rippleIntensity;\nuniform float gridSize;\nuniform float gridThickness;\nuniform float fadeDistance;\nuniform float vignetteStrength;\nuniform float glowIntensity;\nuniform float opacity;\nuniform float gridRotation;\nuniform bool mouseInteraction;\nuniform vec2 mousePosition;\nuniform float mouseInfluence;\nuniform float mouseInteractionRadius;\nvarying vec2 vUv;\n\nfloat pi = 3.141592;\n\nmat2 rotate(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec2 uv = vUv * 2.0 - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n\n if (gridRotation != 0.0) {\n uv = rotate(gridRotation * pi / 180.0) * uv;\n }\n\n float dist = length(uv);\n float func = sin(pi * (iTime - dist));\n vec2 rippleUv = uv + uv * func * rippleIntensity;\n\n if (mouseInteraction && mouseInfluence > 0.0) {\n vec2 mouseUv = (mousePosition * 2.0 - 1.0);\n mouseUv.x *= iResolution.x / iResolution.y;\n float mouseDist = length(uv - mouseUv);\n \n float influence = mouseInfluence * exp(-mouseDist * mouseDist / (mouseInteractionRadius * mouseInteractionRadius));\n \n float mouseWave = sin(pi * (iTime * 2.0 - mouseDist * 3.0)) * influence;\n rippleUv += normalize(uv - mouseUv) * mouseWave * rippleIntensity * 0.3;\n }\n\n vec2 a = sin(gridSize * 0.5 * pi * rippleUv - pi / 2.0);\n vec2 b = abs(a);\n\n float aaWidth = 0.5;\n vec2 smoothB = vec2(\n smoothstep(0.0, aaWidth, b.x),\n smoothstep(0.0, aaWidth, b.y)\n );\n\n vec3 color = vec3(0.0);\n color += exp(-gridThickness * smoothB.x * (0.8 + 0.5 * sin(pi * iTime)));\n color += exp(-gridThickness * smoothB.y);\n color += 0.5 * exp(-(gridThickness / 4.0) * sin(smoothB.x));\n color += 0.5 * exp(-(gridThickness / 3.0) * smoothB.y);\n\n if (glowIntensity > 0.0) {\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.x);\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.y);\n }\n\n float ddd = exp(-2.0 * clamp(pow(dist, fadeDistance), 0.0, 1.0));\n \n vec2 vignetteCoords = vUv - 0.5;\n float vignetteDistance = length(vignetteCoords);\n float vignette = 1.0 - pow(vignetteDistance * 2.0, vignetteStrength);\n vignette = clamp(vignette, 0.0, 1.0);\n \n vec3 t;\n if (enableRainbow) {\n t = vec3(\n uv.x * 0.5 + 0.5 * sin(iTime),\n uv.y * 0.5 + 0.5 * cos(iTime),\n pow(cos(iTime), 4.0)\n ) + 0.5;\n } else {\n t = gridColor;\n }\n\n float finalFade = ddd * vignette;\n float alpha = length(color) * finalFade * opacity;\n gl_FragColor = vec4(color * t * finalFade * opacity, alpha);\n}`;\n\n const uniforms = {\n iTime: { value: 0 },\n iResolution: { value: [1, 1] },\n enableRainbow: { value: enableRainbow },\n gridColor: { value: hexToRgb(gridColor) },\n rippleIntensity: { value: rippleIntensity },\n gridSize: { value: gridSize },\n gridThickness: { value: gridThickness },\n fadeDistance: { value: fadeDistance },\n vignetteStrength: { value: vignetteStrength },\n glowIntensity: { value: glowIntensity },\n opacity: { value: opacity },\n gridRotation: { value: gridRotation },\n mouseInteraction: { value: mouseInteraction },\n mousePosition: { value: [0.5, 0.5] },\n mouseInfluence: { value: 0 },\n mouseInteractionRadius: { value: mouseInteractionRadius }\n };\n\n uniformsRef.current = uniforms;\n\n const geometry = new Triangle(gl);\n const program = new Program(gl, { vertex: vert, fragment: frag, uniforms });\n const mesh = new Mesh(gl, { geometry, program });\n\n const resize = () => {\n const { clientWidth: w, clientHeight: h } = containerRef.current;\n renderer.setSize(w, h);\n uniforms.iResolution.value = [w, h];\n };\n\n const handleMouseMove = e => {\n if (!mouseInteraction || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = 1.0 - (e.clientY - rect.top) / rect.height; // Flip Y coordinate\n targetMouseRef.current = { x, y };\n };\n\n const handleMouseEnter = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 1.0;\n };\n\n const handleMouseLeave = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 0.0;\n };\n\n window.addEventListener('resize', resize);\n if (mouseInteraction) {\n containerRef.current.addEventListener('mousemove', handleMouseMove);\n containerRef.current.addEventListener('mouseenter', handleMouseEnter);\n containerRef.current.addEventListener('mouseleave', handleMouseLeave);\n }\n resize();\n\n let animationFrameId;\n const render = t => {\n uniforms.iTime.value = t * 0.001;\n\n const lerpFactor = 0.1;\n mousePositionRef.current.x += (targetMouseRef.current.x - mousePositionRef.current.x) * lerpFactor;\n mousePositionRef.current.y += (targetMouseRef.current.y - mousePositionRef.current.y) * lerpFactor;\n\n const currentInfluence = uniforms.mouseInfluence.value;\n const targetInfluence = mouseInfluenceRef.current;\n uniforms.mouseInfluence.value += (targetInfluence - currentInfluence) * 0.05;\n\n uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y];\n\n renderer.render({ scene: mesh });\n animationFrameId = requestAnimationFrame(render);\n };\n\n animationFrameId = requestAnimationFrame(render);\n\n const container = containerRef.current;\n return () => {\n cancelAnimationFrame(animationFrameId);\n window.removeEventListener('resize', resize);\n if (mouseInteraction && container) {\n container.removeEventListener('mousemove', handleMouseMove);\n container.removeEventListener('mouseenter', handleMouseEnter);\n container.removeEventListener('mouseleave', handleMouseLeave);\n }\n renderer.gl.getExtension('WEBGL_lose_context')?.loseContext();\n container?.removeChild(gl.canvas);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n useEffect(() => {\n if (!uniformsRef.current) return;\n\n const hexToRgb = hex => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n uniformsRef.current.enableRainbow.value = enableRainbow;\n uniformsRef.current.gridColor.value = hexToRgb(gridColor);\n uniformsRef.current.rippleIntensity.value = rippleIntensity;\n uniformsRef.current.gridSize.value = gridSize;\n uniformsRef.current.gridThickness.value = gridThickness;\n uniformsRef.current.fadeDistance.value = fadeDistance;\n uniformsRef.current.vignetteStrength.value = vignetteStrength;\n uniformsRef.current.glowIntensity.value = glowIntensity;\n uniformsRef.current.opacity.value = opacity;\n uniformsRef.current.gridRotation.value = gridRotation;\n uniformsRef.current.mouseInteraction.value = mouseInteraction;\n uniformsRef.current.mouseInteractionRadius.value = mouseInteractionRadius;\n }, [\n enableRainbow,\n gridColor,\n rippleIntensity,\n gridSize,\n gridThickness,\n fadeDistance,\n vignetteStrength,\n glowIntensity,\n opacity,\n gridRotation,\n mouseInteraction,\n mouseInteractionRadius\n ]);\n\n return
;\n};\n\nexport default RippleGrid;\n" } ], "registryDependencies": [], diff --git a/public/r/RippleGrid-TS-CSS.json b/public/r/RippleGrid-TS-CSS.json index 00387da4d..b16b43d90 100644 --- a/public/r/RippleGrid-TS-CSS.json +++ b/public/r/RippleGrid-TS-CSS.json @@ -13,7 +13,7 @@ { "type": "registry:component", "path": "RippleGrid/RippleGrid.tsx", - "content": "import { useRef, useEffect } from 'react';\nimport { Renderer, Program, Triangle, Mesh } from 'ogl';\nimport './RippleGrid.css';\n\ntype Props = {\n enableRainbow?: boolean;\n gridColor?: string;\n rippleIntensity?: number;\n gridSize?: number;\n gridThickness?: number;\n fadeDistance?: number;\n vignetteStrength?: number;\n glowIntensity?: number;\n opacity?: number;\n gridRotation?: number;\n mouseInteraction?: boolean;\n mouseInteractionRadius?: number;\n};\n\nconst RippleGrid: React.FC = ({\n enableRainbow = false,\n gridColor = '#ffffff',\n rippleIntensity = 0.05,\n gridSize = 10.0,\n gridThickness = 15.0,\n fadeDistance = 1.5,\n vignetteStrength = 2.0,\n glowIntensity = 0.1,\n opacity = 1.0,\n gridRotation = 0,\n mouseInteraction = true,\n mouseInteractionRadius = 1\n}) => {\n const containerRef = useRef(null);\n const mousePositionRef = useRef({ x: 0.5, y: 0.5 });\n const targetMouseRef = useRef({ x: 0.5, y: 0.5 });\n const mouseInfluenceRef = useRef(0);\n const uniformsRef = useRef(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const hexToRgb = (hex: string): [number, number, number] => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n const renderer = new Renderer({\n dpr: Math.min(window.devicePixelRatio, 2),\n alpha: true\n });\n const gl = renderer.gl;\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.canvas.style.width = '100%';\n gl.canvas.style.height = '100%';\n containerRef.current.appendChild(gl.canvas);\n\n const vert = `\nattribute vec2 position;\nvarying vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n const frag = `precision highp float;\nuniform float iTime;\nuniform vec2 iResolution;\nuniform bool enableRainbow;\nuniform vec3 gridColor;\nuniform float rippleIntensity;\nuniform float gridSize;\nuniform float gridThickness;\nuniform float fadeDistance;\nuniform float vignetteStrength;\nuniform float glowIntensity;\nuniform float opacity;\nuniform float gridRotation;\nuniform bool mouseInteraction;\nuniform vec2 mousePosition;\nuniform float mouseInfluence;\nuniform float mouseInteractionRadius;\nvarying vec2 vUv;\n\nfloat pi = 3.141592;\n\nmat2 rotate(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec2 uv = vUv * 2.0 - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n\n if (gridRotation != 0.0) {\n uv = rotate(gridRotation * pi / 180.0) * uv;\n }\n\n float dist = length(uv);\n float func = sin(pi * (iTime - dist));\n vec2 rippleUv = uv + uv * func * rippleIntensity;\n\n if (mouseInteraction && mouseInfluence > 0.0) {\n vec2 mouseUv = (mousePosition * 2.0 - 1.0);\n mouseUv.x *= iResolution.x / iResolution.y;\n float mouseDist = length(uv - mouseUv);\n \n float influence = mouseInfluence * exp(-mouseDist * mouseDist / (mouseInteractionRadius * mouseInteractionRadius));\n \n float mouseWave = sin(pi * (iTime * 2.0 - mouseDist * 3.0)) * influence;\n rippleUv += normalize(uv - mouseUv) * mouseWave * rippleIntensity * 0.3;\n }\n\n vec2 a = sin(gridSize * 0.5 * pi * rippleUv - pi / 2.0);\n vec2 b = abs(a);\n\n float aaWidth = 0.5;\n vec2 smoothB = vec2(\n smoothstep(0.0, aaWidth, b.x),\n smoothstep(0.0, aaWidth, b.y)\n );\n\n vec3 color = vec3(0.0);\n color += exp(-gridThickness * smoothB.x * (0.8 + 0.5 * sin(pi * iTime)));\n color += exp(-gridThickness * smoothB.y);\n color += 0.5 * exp(-(gridThickness / 4.0) * sin(smoothB.x));\n color += 0.5 * exp(-(gridThickness / 3.0) * smoothB.y);\n\n if (glowIntensity > 0.0) {\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.x);\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.y);\n }\n\n float ddd = exp(-2.0 * clamp(pow(dist, fadeDistance), 0.0, 1.0));\n \n vec2 vignetteCoords = vUv - 0.5;\n float vignetteDistance = length(vignetteCoords);\n float vignette = 1.0 - pow(vignetteDistance * 2.0, vignetteStrength);\n vignette = clamp(vignette, 0.0, 1.0);\n \n vec3 t;\n if (enableRainbow) {\n t = vec3(\n uv.x * 0.5 + 0.5 * sin(iTime),\n uv.y * 0.5 + 0.5 * cos(iTime),\n pow(cos(iTime), 4.0)\n ) + 0.5;\n } else {\n t = gridColor;\n }\n\n float finalFade = ddd * vignette;\n float alpha = length(color) * finalFade * opacity;\n gl_FragColor = vec4(color * t * finalFade * opacity, alpha);\n}`;\n\n const uniforms = {\n iTime: { value: 0 },\n iResolution: { value: [1, 1] },\n enableRainbow: { value: enableRainbow },\n gridColor: { value: hexToRgb(gridColor) },\n rippleIntensity: { value: rippleIntensity },\n gridSize: { value: gridSize },\n gridThickness: { value: gridThickness },\n fadeDistance: { value: fadeDistance },\n vignetteStrength: { value: vignetteStrength },\n glowIntensity: { value: glowIntensity },\n opacity: { value: opacity },\n gridRotation: { value: gridRotation },\n mouseInteraction: { value: mouseInteraction },\n mousePosition: { value: [0.5, 0.5] },\n mouseInfluence: { value: 0 },\n mouseInteractionRadius: { value: mouseInteractionRadius }\n };\n\n uniformsRef.current = uniforms;\n\n const geometry = new Triangle(gl);\n const program = new Program(gl, { vertex: vert, fragment: frag, uniforms });\n const mesh = new Mesh(gl, { geometry, program });\n\n const resize = () => {\n const { clientWidth: w, clientHeight: h } = containerRef.current!;\n renderer.setSize(w, h);\n uniforms.iResolution.value = [w, h];\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!mouseInteraction || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = 1.0 - (e.clientY - rect.top) / rect.height;\n targetMouseRef.current = { x, y };\n };\n\n const handleMouseEnter = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 1.0;\n };\n\n const handleMouseLeave = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 0.0;\n };\n\n window.addEventListener('resize', resize);\n if (mouseInteraction) {\n containerRef.current.addEventListener('mousemove', handleMouseMove);\n containerRef.current.addEventListener('mouseenter', handleMouseEnter);\n containerRef.current.addEventListener('mouseleave', handleMouseLeave);\n }\n resize();\n\n const render = (t: number) => {\n uniforms.iTime.value = t * 0.001;\n\n const lerpFactor = 0.1;\n mousePositionRef.current.x += (targetMouseRef.current.x - mousePositionRef.current.x) * lerpFactor;\n mousePositionRef.current.y += (targetMouseRef.current.y - mousePositionRef.current.y) * lerpFactor;\n\n const currentInfluence = uniforms.mouseInfluence.value;\n const targetInfluence = mouseInfluenceRef.current;\n uniforms.mouseInfluence.value += (targetInfluence - currentInfluence) * 0.05;\n\n uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y];\n\n renderer.render({ scene: mesh });\n requestAnimationFrame(render);\n };\n\n requestAnimationFrame(render);\n\n return () => {\n window.removeEventListener('resize', resize);\n if (mouseInteraction && containerRef.current) {\n containerRef.current.removeEventListener('mousemove', handleMouseMove);\n containerRef.current.removeEventListener('mouseenter', handleMouseEnter);\n containerRef.current.removeEventListener('mouseleave', handleMouseLeave);\n }\n renderer.gl.getExtension('WEBGL_lose_context')?.loseContext();\n containerRef.current?.removeChild(gl.canvas);\n };\n }, []);\n\n useEffect(() => {\n if (!uniformsRef.current) return;\n\n const hexToRgb = (hex: string): [number, number, number] => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n uniformsRef.current.enableRainbow.value = enableRainbow;\n uniformsRef.current.gridColor.value = hexToRgb(gridColor);\n uniformsRef.current.rippleIntensity.value = rippleIntensity;\n uniformsRef.current.gridSize.value = gridSize;\n uniformsRef.current.gridThickness.value = gridThickness;\n uniformsRef.current.fadeDistance.value = fadeDistance;\n uniformsRef.current.vignetteStrength.value = vignetteStrength;\n uniformsRef.current.glowIntensity.value = glowIntensity;\n uniformsRef.current.opacity.value = opacity;\n uniformsRef.current.gridRotation.value = gridRotation;\n uniformsRef.current.mouseInteraction.value = mouseInteraction;\n uniformsRef.current.mouseInteractionRadius.value = mouseInteractionRadius;\n }, [\n enableRainbow,\n gridColor,\n rippleIntensity,\n gridSize,\n gridThickness,\n fadeDistance,\n vignetteStrength,\n glowIntensity,\n opacity,\n gridRotation,\n mouseInteraction,\n mouseInteractionRadius\n ]);\n\n return
;\n};\n\nexport default RippleGrid;\n" + "content": "import { useRef, useEffect } from 'react';\nimport { Renderer, Program, Triangle, Mesh } from 'ogl';\nimport './RippleGrid.css';\n\ntype Props = {\n enableRainbow?: boolean;\n gridColor?: string;\n rippleIntensity?: number;\n gridSize?: number;\n gridThickness?: number;\n fadeDistance?: number;\n vignetteStrength?: number;\n glowIntensity?: number;\n opacity?: number;\n gridRotation?: number;\n mouseInteraction?: boolean;\n mouseInteractionRadius?: number;\n};\n\nconst RippleGrid: React.FC = ({\n enableRainbow = false,\n gridColor = '#ffffff',\n rippleIntensity = 0.05,\n gridSize = 10.0,\n gridThickness = 15.0,\n fadeDistance = 1.5,\n vignetteStrength = 2.0,\n glowIntensity = 0.1,\n opacity = 1.0,\n gridRotation = 0,\n mouseInteraction = true,\n mouseInteractionRadius = 1\n}) => {\n const containerRef = useRef(null);\n const mousePositionRef = useRef({ x: 0.5, y: 0.5 });\n const targetMouseRef = useRef({ x: 0.5, y: 0.5 });\n const mouseInfluenceRef = useRef(0);\n const uniformsRef = useRef(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const hexToRgb = (hex: string): [number, number, number] => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n const renderer = new Renderer({\n dpr: Math.min(window.devicePixelRatio, 2),\n alpha: true\n });\n const gl = renderer.gl;\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.canvas.style.width = '100%';\n gl.canvas.style.height = '100%';\n containerRef.current.appendChild(gl.canvas);\n\n const vert = `\nattribute vec2 position;\nvarying vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n const frag = `precision highp float;\nuniform float iTime;\nuniform vec2 iResolution;\nuniform bool enableRainbow;\nuniform vec3 gridColor;\nuniform float rippleIntensity;\nuniform float gridSize;\nuniform float gridThickness;\nuniform float fadeDistance;\nuniform float vignetteStrength;\nuniform float glowIntensity;\nuniform float opacity;\nuniform float gridRotation;\nuniform bool mouseInteraction;\nuniform vec2 mousePosition;\nuniform float mouseInfluence;\nuniform float mouseInteractionRadius;\nvarying vec2 vUv;\n\nfloat pi = 3.141592;\n\nmat2 rotate(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec2 uv = vUv * 2.0 - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n\n if (gridRotation != 0.0) {\n uv = rotate(gridRotation * pi / 180.0) * uv;\n }\n\n float dist = length(uv);\n float func = sin(pi * (iTime - dist));\n vec2 rippleUv = uv + uv * func * rippleIntensity;\n\n if (mouseInteraction && mouseInfluence > 0.0) {\n vec2 mouseUv = (mousePosition * 2.0 - 1.0);\n mouseUv.x *= iResolution.x / iResolution.y;\n float mouseDist = length(uv - mouseUv);\n \n float influence = mouseInfluence * exp(-mouseDist * mouseDist / (mouseInteractionRadius * mouseInteractionRadius));\n \n float mouseWave = sin(pi * (iTime * 2.0 - mouseDist * 3.0)) * influence;\n rippleUv += normalize(uv - mouseUv) * mouseWave * rippleIntensity * 0.3;\n }\n\n vec2 a = sin(gridSize * 0.5 * pi * rippleUv - pi / 2.0);\n vec2 b = abs(a);\n\n float aaWidth = 0.5;\n vec2 smoothB = vec2(\n smoothstep(0.0, aaWidth, b.x),\n smoothstep(0.0, aaWidth, b.y)\n );\n\n vec3 color = vec3(0.0);\n color += exp(-gridThickness * smoothB.x * (0.8 + 0.5 * sin(pi * iTime)));\n color += exp(-gridThickness * smoothB.y);\n color += 0.5 * exp(-(gridThickness / 4.0) * sin(smoothB.x));\n color += 0.5 * exp(-(gridThickness / 3.0) * smoothB.y);\n\n if (glowIntensity > 0.0) {\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.x);\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.y);\n }\n\n float ddd = exp(-2.0 * clamp(pow(dist, fadeDistance), 0.0, 1.0));\n \n vec2 vignetteCoords = vUv - 0.5;\n float vignetteDistance = length(vignetteCoords);\n float vignette = 1.0 - pow(vignetteDistance * 2.0, vignetteStrength);\n vignette = clamp(vignette, 0.0, 1.0);\n \n vec3 t;\n if (enableRainbow) {\n t = vec3(\n uv.x * 0.5 + 0.5 * sin(iTime),\n uv.y * 0.5 + 0.5 * cos(iTime),\n pow(cos(iTime), 4.0)\n ) + 0.5;\n } else {\n t = gridColor;\n }\n\n float finalFade = ddd * vignette;\n float alpha = length(color) * finalFade * opacity;\n gl_FragColor = vec4(color * t * finalFade * opacity, alpha);\n}`;\n\n const uniforms = {\n iTime: { value: 0 },\n iResolution: { value: [1, 1] },\n enableRainbow: { value: enableRainbow },\n gridColor: { value: hexToRgb(gridColor) },\n rippleIntensity: { value: rippleIntensity },\n gridSize: { value: gridSize },\n gridThickness: { value: gridThickness },\n fadeDistance: { value: fadeDistance },\n vignetteStrength: { value: vignetteStrength },\n glowIntensity: { value: glowIntensity },\n opacity: { value: opacity },\n gridRotation: { value: gridRotation },\n mouseInteraction: { value: mouseInteraction },\n mousePosition: { value: [0.5, 0.5] },\n mouseInfluence: { value: 0 },\n mouseInteractionRadius: { value: mouseInteractionRadius }\n };\n\n uniformsRef.current = uniforms;\n\n const geometry = new Triangle(gl);\n const program = new Program(gl, { vertex: vert, fragment: frag, uniforms });\n const mesh = new Mesh(gl, { geometry, program });\n\n const resize = () => {\n const { clientWidth: w, clientHeight: h } = containerRef.current!;\n renderer.setSize(w, h);\n uniforms.iResolution.value = [w, h];\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!mouseInteraction || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = 1.0 - (e.clientY - rect.top) / rect.height;\n targetMouseRef.current = { x, y };\n };\n\n const handleMouseEnter = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 1.0;\n };\n\n const handleMouseLeave = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 0.0;\n };\n\n window.addEventListener('resize', resize);\n if (mouseInteraction) {\n containerRef.current.addEventListener('mousemove', handleMouseMove);\n containerRef.current.addEventListener('mouseenter', handleMouseEnter);\n containerRef.current.addEventListener('mouseleave', handleMouseLeave);\n }\n resize();\n\n let animationFrameId: number;\n const render = (t: number) => {\n uniforms.iTime.value = t * 0.001;\n\n const lerpFactor = 0.1;\n mousePositionRef.current.x += (targetMouseRef.current.x - mousePositionRef.current.x) * lerpFactor;\n mousePositionRef.current.y += (targetMouseRef.current.y - mousePositionRef.current.y) * lerpFactor;\n\n const currentInfluence = uniforms.mouseInfluence.value;\n const targetInfluence = mouseInfluenceRef.current;\n uniforms.mouseInfluence.value += (targetInfluence - currentInfluence) * 0.05;\n\n uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y];\n\n renderer.render({ scene: mesh });\n animationFrameId = requestAnimationFrame(render);\n };\n\n animationFrameId = requestAnimationFrame(render);\n\n return () => {\n cancelAnimationFrame(animationFrameId);\n window.removeEventListener('resize', resize);\n if (mouseInteraction && containerRef.current) {\n containerRef.current.removeEventListener('mousemove', handleMouseMove);\n containerRef.current.removeEventListener('mouseenter', handleMouseEnter);\n containerRef.current.removeEventListener('mouseleave', handleMouseLeave);\n }\n renderer.gl.getExtension('WEBGL_lose_context')?.loseContext();\n containerRef.current?.removeChild(gl.canvas);\n };\n }, []);\n\n useEffect(() => {\n if (!uniformsRef.current) return;\n\n const hexToRgb = (hex: string): [number, number, number] => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n uniformsRef.current.enableRainbow.value = enableRainbow;\n uniformsRef.current.gridColor.value = hexToRgb(gridColor);\n uniformsRef.current.rippleIntensity.value = rippleIntensity;\n uniformsRef.current.gridSize.value = gridSize;\n uniformsRef.current.gridThickness.value = gridThickness;\n uniformsRef.current.fadeDistance.value = fadeDistance;\n uniformsRef.current.vignetteStrength.value = vignetteStrength;\n uniformsRef.current.glowIntensity.value = glowIntensity;\n uniformsRef.current.opacity.value = opacity;\n uniformsRef.current.gridRotation.value = gridRotation;\n uniformsRef.current.mouseInteraction.value = mouseInteraction;\n uniformsRef.current.mouseInteractionRadius.value = mouseInteractionRadius;\n }, [\n enableRainbow,\n gridColor,\n rippleIntensity,\n gridSize,\n gridThickness,\n fadeDistance,\n vignetteStrength,\n glowIntensity,\n opacity,\n gridRotation,\n mouseInteraction,\n mouseInteractionRadius\n ]);\n\n return
;\n};\n\nexport default RippleGrid;\n" } ], "registryDependencies": [], diff --git a/public/r/RippleGrid-TS-TW.json b/public/r/RippleGrid-TS-TW.json index f4845eddb..d459bfa24 100644 --- a/public/r/RippleGrid-TS-TW.json +++ b/public/r/RippleGrid-TS-TW.json @@ -8,7 +8,7 @@ { "type": "registry:component", "path": "RippleGrid/RippleGrid.tsx", - "content": "import { useRef, useEffect } from 'react';\nimport { Renderer, Program, Triangle, Mesh } from 'ogl';\n\ntype Props = {\n enableRainbow?: boolean;\n gridColor?: string;\n rippleIntensity?: number;\n gridSize?: number;\n gridThickness?: number;\n fadeDistance?: number;\n vignetteStrength?: number;\n glowIntensity?: number;\n opacity?: number;\n gridRotation?: number;\n mouseInteraction?: boolean;\n mouseInteractionRadius?: number;\n};\n\nconst RippleGrid: React.FC = ({\n enableRainbow = false,\n gridColor = '#ffffff',\n rippleIntensity = 0.05,\n gridSize = 10.0,\n gridThickness = 15.0,\n fadeDistance = 1.5,\n vignetteStrength = 2.0,\n glowIntensity = 0.1,\n opacity = 1.0,\n gridRotation = 0,\n mouseInteraction = true,\n mouseInteractionRadius = 1\n}) => {\n const containerRef = useRef(null);\n const mousePositionRef = useRef({ x: 0.5, y: 0.5 });\n const targetMouseRef = useRef({ x: 0.5, y: 0.5 });\n const mouseInfluenceRef = useRef(0);\n const uniformsRef = useRef(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const hexToRgb = (hex: string): [number, number, number] => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n const renderer = new Renderer({\n dpr: Math.min(window.devicePixelRatio, 2),\n alpha: true\n });\n const gl = renderer.gl;\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.canvas.style.width = '100%';\n gl.canvas.style.height = '100%';\n containerRef.current.appendChild(gl.canvas);\n\n const vert = `\nattribute vec2 position;\nvarying vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n const frag = `precision highp float;\nuniform float iTime;\nuniform vec2 iResolution;\nuniform bool enableRainbow;\nuniform vec3 gridColor;\nuniform float rippleIntensity;\nuniform float gridSize;\nuniform float gridThickness;\nuniform float fadeDistance;\nuniform float vignetteStrength;\nuniform float glowIntensity;\nuniform float opacity;\nuniform float gridRotation;\nuniform bool mouseInteraction;\nuniform vec2 mousePosition;\nuniform float mouseInfluence;\nuniform float mouseInteractionRadius;\nvarying vec2 vUv;\n\nfloat pi = 3.141592;\n\nmat2 rotate(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec2 uv = vUv * 2.0 - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n\n if (gridRotation != 0.0) {\n uv = rotate(gridRotation * pi / 180.0) * uv;\n }\n\n float dist = length(uv);\n float func = sin(pi * (iTime - dist));\n vec2 rippleUv = uv + uv * func * rippleIntensity;\n\n if (mouseInteraction && mouseInfluence > 0.0) {\n vec2 mouseUv = (mousePosition * 2.0 - 1.0);\n mouseUv.x *= iResolution.x / iResolution.y;\n float mouseDist = length(uv - mouseUv);\n \n float influence = mouseInfluence * exp(-mouseDist * mouseDist / (mouseInteractionRadius * mouseInteractionRadius));\n \n float mouseWave = sin(pi * (iTime * 2.0 - mouseDist * 3.0)) * influence;\n rippleUv += normalize(uv - mouseUv) * mouseWave * rippleIntensity * 0.3;\n }\n\n vec2 a = sin(gridSize * 0.5 * pi * rippleUv - pi / 2.0);\n vec2 b = abs(a);\n\n float aaWidth = 0.5;\n vec2 smoothB = vec2(\n smoothstep(0.0, aaWidth, b.x),\n smoothstep(0.0, aaWidth, b.y)\n );\n\n vec3 color = vec3(0.0);\n color += exp(-gridThickness * smoothB.x * (0.8 + 0.5 * sin(pi * iTime)));\n color += exp(-gridThickness * smoothB.y);\n color += 0.5 * exp(-(gridThickness / 4.0) * sin(smoothB.x));\n color += 0.5 * exp(-(gridThickness / 3.0) * smoothB.y);\n\n if (glowIntensity > 0.0) {\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.x);\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.y);\n }\n\n float ddd = exp(-2.0 * clamp(pow(dist, fadeDistance), 0.0, 1.0));\n \n vec2 vignetteCoords = vUv - 0.5;\n float vignetteDistance = length(vignetteCoords);\n float vignette = 1.0 - pow(vignetteDistance * 2.0, vignetteStrength);\n vignette = clamp(vignette, 0.0, 1.0);\n \n vec3 t;\n if (enableRainbow) {\n t = vec3(\n uv.x * 0.5 + 0.5 * sin(iTime),\n uv.y * 0.5 + 0.5 * cos(iTime),\n pow(cos(iTime), 4.0)\n ) + 0.5;\n } else {\n t = gridColor;\n }\n\n float finalFade = ddd * vignette;\n float alpha = length(color) * finalFade * opacity;\n gl_FragColor = vec4(color * t * finalFade * opacity, alpha);\n}`;\n\n const uniforms = {\n iTime: { value: 0 },\n iResolution: { value: [1, 1] },\n enableRainbow: { value: enableRainbow },\n gridColor: { value: hexToRgb(gridColor) },\n rippleIntensity: { value: rippleIntensity },\n gridSize: { value: gridSize },\n gridThickness: { value: gridThickness },\n fadeDistance: { value: fadeDistance },\n vignetteStrength: { value: vignetteStrength },\n glowIntensity: { value: glowIntensity },\n opacity: { value: opacity },\n gridRotation: { value: gridRotation },\n mouseInteraction: { value: mouseInteraction },\n mousePosition: { value: [0.5, 0.5] },\n mouseInfluence: { value: 0 },\n mouseInteractionRadius: { value: mouseInteractionRadius }\n };\n\n uniformsRef.current = uniforms;\n\n const geometry = new Triangle(gl);\n const program = new Program(gl, { vertex: vert, fragment: frag, uniforms });\n const mesh = new Mesh(gl, { geometry, program });\n\n const resize = () => {\n const { clientWidth: w, clientHeight: h } = containerRef.current!;\n renderer.setSize(w, h);\n uniforms.iResolution.value = [w, h];\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!mouseInteraction || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = 1.0 - (e.clientY - rect.top) / rect.height;\n targetMouseRef.current = { x, y };\n };\n\n const handleMouseEnter = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 1.0;\n };\n\n const handleMouseLeave = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 0.0;\n };\n\n window.addEventListener('resize', resize);\n if (mouseInteraction) {\n containerRef.current.addEventListener('mousemove', handleMouseMove);\n containerRef.current.addEventListener('mouseenter', handleMouseEnter);\n containerRef.current.addEventListener('mouseleave', handleMouseLeave);\n }\n resize();\n\n const render = (t: number) => {\n uniforms.iTime.value = t * 0.001;\n\n const lerpFactor = 0.1;\n mousePositionRef.current.x += (targetMouseRef.current.x - mousePositionRef.current.x) * lerpFactor;\n mousePositionRef.current.y += (targetMouseRef.current.y - mousePositionRef.current.y) * lerpFactor;\n\n const currentInfluence = uniforms.mouseInfluence.value;\n const targetInfluence = mouseInfluenceRef.current;\n uniforms.mouseInfluence.value += (targetInfluence - currentInfluence) * 0.05;\n\n uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y];\n\n renderer.render({ scene: mesh });\n requestAnimationFrame(render);\n };\n\n requestAnimationFrame(render);\n\n return () => {\n window.removeEventListener('resize', resize);\n if (mouseInteraction && containerRef.current) {\n containerRef.current.removeEventListener('mousemove', handleMouseMove);\n containerRef.current.removeEventListener('mouseenter', handleMouseEnter);\n containerRef.current.removeEventListener('mouseleave', handleMouseLeave);\n }\n renderer.gl.getExtension('WEBGL_lose_context')?.loseContext();\n containerRef.current?.removeChild(gl.canvas);\n };\n }, []);\n\n useEffect(() => {\n if (!uniformsRef.current) return;\n\n const hexToRgb = (hex: string): [number, number, number] => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n uniformsRef.current.enableRainbow.value = enableRainbow;\n uniformsRef.current.gridColor.value = hexToRgb(gridColor);\n uniformsRef.current.rippleIntensity.value = rippleIntensity;\n uniformsRef.current.gridSize.value = gridSize;\n uniformsRef.current.gridThickness.value = gridThickness;\n uniformsRef.current.fadeDistance.value = fadeDistance;\n uniformsRef.current.vignetteStrength.value = vignetteStrength;\n uniformsRef.current.glowIntensity.value = glowIntensity;\n uniformsRef.current.opacity.value = opacity;\n uniformsRef.current.gridRotation.value = gridRotation;\n uniformsRef.current.mouseInteraction.value = mouseInteraction;\n uniformsRef.current.mouseInteractionRadius.value = mouseInteractionRadius;\n }, [\n enableRainbow,\n gridColor,\n rippleIntensity,\n gridSize,\n gridThickness,\n fadeDistance,\n vignetteStrength,\n glowIntensity,\n opacity,\n gridRotation,\n mouseInteraction,\n mouseInteractionRadius\n ]);\n\n return
;\n};\n\nexport default RippleGrid;\n" + "content": "import { useRef, useEffect } from 'react';\nimport { Renderer, Program, Triangle, Mesh } from 'ogl';\n\ntype Props = {\n enableRainbow?: boolean;\n gridColor?: string;\n rippleIntensity?: number;\n gridSize?: number;\n gridThickness?: number;\n fadeDistance?: number;\n vignetteStrength?: number;\n glowIntensity?: number;\n opacity?: number;\n gridRotation?: number;\n mouseInteraction?: boolean;\n mouseInteractionRadius?: number;\n};\n\nconst RippleGrid: React.FC = ({\n enableRainbow = false,\n gridColor = '#ffffff',\n rippleIntensity = 0.05,\n gridSize = 10.0,\n gridThickness = 15.0,\n fadeDistance = 1.5,\n vignetteStrength = 2.0,\n glowIntensity = 0.1,\n opacity = 1.0,\n gridRotation = 0,\n mouseInteraction = true,\n mouseInteractionRadius = 1\n}) => {\n const containerRef = useRef(null);\n const mousePositionRef = useRef({ x: 0.5, y: 0.5 });\n const targetMouseRef = useRef({ x: 0.5, y: 0.5 });\n const mouseInfluenceRef = useRef(0);\n const uniformsRef = useRef(null);\n\n useEffect(() => {\n if (!containerRef.current) return;\n\n const hexToRgb = (hex: string): [number, number, number] => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n const renderer = new Renderer({\n dpr: Math.min(window.devicePixelRatio, 2),\n alpha: true\n });\n const gl = renderer.gl;\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n gl.canvas.style.width = '100%';\n gl.canvas.style.height = '100%';\n containerRef.current.appendChild(gl.canvas);\n\n const vert = `\nattribute vec2 position;\nvarying vec2 vUv;\nvoid main() {\n vUv = position * 0.5 + 0.5;\n gl_Position = vec4(position, 0.0, 1.0);\n}`;\n\n const frag = `precision highp float;\nuniform float iTime;\nuniform vec2 iResolution;\nuniform bool enableRainbow;\nuniform vec3 gridColor;\nuniform float rippleIntensity;\nuniform float gridSize;\nuniform float gridThickness;\nuniform float fadeDistance;\nuniform float vignetteStrength;\nuniform float glowIntensity;\nuniform float opacity;\nuniform float gridRotation;\nuniform bool mouseInteraction;\nuniform vec2 mousePosition;\nuniform float mouseInfluence;\nuniform float mouseInteractionRadius;\nvarying vec2 vUv;\n\nfloat pi = 3.141592;\n\nmat2 rotate(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec2 uv = vUv * 2.0 - 1.0;\n uv.x *= iResolution.x / iResolution.y;\n\n if (gridRotation != 0.0) {\n uv = rotate(gridRotation * pi / 180.0) * uv;\n }\n\n float dist = length(uv);\n float func = sin(pi * (iTime - dist));\n vec2 rippleUv = uv + uv * func * rippleIntensity;\n\n if (mouseInteraction && mouseInfluence > 0.0) {\n vec2 mouseUv = (mousePosition * 2.0 - 1.0);\n mouseUv.x *= iResolution.x / iResolution.y;\n float mouseDist = length(uv - mouseUv);\n \n float influence = mouseInfluence * exp(-mouseDist * mouseDist / (mouseInteractionRadius * mouseInteractionRadius));\n \n float mouseWave = sin(pi * (iTime * 2.0 - mouseDist * 3.0)) * influence;\n rippleUv += normalize(uv - mouseUv) * mouseWave * rippleIntensity * 0.3;\n }\n\n vec2 a = sin(gridSize * 0.5 * pi * rippleUv - pi / 2.0);\n vec2 b = abs(a);\n\n float aaWidth = 0.5;\n vec2 smoothB = vec2(\n smoothstep(0.0, aaWidth, b.x),\n smoothstep(0.0, aaWidth, b.y)\n );\n\n vec3 color = vec3(0.0);\n color += exp(-gridThickness * smoothB.x * (0.8 + 0.5 * sin(pi * iTime)));\n color += exp(-gridThickness * smoothB.y);\n color += 0.5 * exp(-(gridThickness / 4.0) * sin(smoothB.x));\n color += 0.5 * exp(-(gridThickness / 3.0) * smoothB.y);\n\n if (glowIntensity > 0.0) {\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.x);\n color += glowIntensity * exp(-gridThickness * 0.5 * smoothB.y);\n }\n\n float ddd = exp(-2.0 * clamp(pow(dist, fadeDistance), 0.0, 1.0));\n \n vec2 vignetteCoords = vUv - 0.5;\n float vignetteDistance = length(vignetteCoords);\n float vignette = 1.0 - pow(vignetteDistance * 2.0, vignetteStrength);\n vignette = clamp(vignette, 0.0, 1.0);\n \n vec3 t;\n if (enableRainbow) {\n t = vec3(\n uv.x * 0.5 + 0.5 * sin(iTime),\n uv.y * 0.5 + 0.5 * cos(iTime),\n pow(cos(iTime), 4.0)\n ) + 0.5;\n } else {\n t = gridColor;\n }\n\n float finalFade = ddd * vignette;\n float alpha = length(color) * finalFade * opacity;\n gl_FragColor = vec4(color * t * finalFade * opacity, alpha);\n}`;\n\n const uniforms = {\n iTime: { value: 0 },\n iResolution: { value: [1, 1] },\n enableRainbow: { value: enableRainbow },\n gridColor: { value: hexToRgb(gridColor) },\n rippleIntensity: { value: rippleIntensity },\n gridSize: { value: gridSize },\n gridThickness: { value: gridThickness },\n fadeDistance: { value: fadeDistance },\n vignetteStrength: { value: vignetteStrength },\n glowIntensity: { value: glowIntensity },\n opacity: { value: opacity },\n gridRotation: { value: gridRotation },\n mouseInteraction: { value: mouseInteraction },\n mousePosition: { value: [0.5, 0.5] },\n mouseInfluence: { value: 0 },\n mouseInteractionRadius: { value: mouseInteractionRadius }\n };\n\n uniformsRef.current = uniforms;\n\n const geometry = new Triangle(gl);\n const program = new Program(gl, { vertex: vert, fragment: frag, uniforms });\n const mesh = new Mesh(gl, { geometry, program });\n\n const resize = () => {\n const { clientWidth: w, clientHeight: h } = containerRef.current!;\n renderer.setSize(w, h);\n uniforms.iResolution.value = [w, h];\n };\n\n const handleMouseMove = (e: MouseEvent) => {\n if (!mouseInteraction || !containerRef.current) return;\n const rect = containerRef.current.getBoundingClientRect();\n const x = (e.clientX - rect.left) / rect.width;\n const y = 1.0 - (e.clientY - rect.top) / rect.height;\n targetMouseRef.current = { x, y };\n };\n\n const handleMouseEnter = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 1.0;\n };\n\n const handleMouseLeave = () => {\n if (!mouseInteraction) return;\n mouseInfluenceRef.current = 0.0;\n };\n\n window.addEventListener('resize', resize);\n if (mouseInteraction) {\n containerRef.current.addEventListener('mousemove', handleMouseMove);\n containerRef.current.addEventListener('mouseenter', handleMouseEnter);\n containerRef.current.addEventListener('mouseleave', handleMouseLeave);\n }\n resize();\n\n let animationFrameId: number;\n const render = (t: number) => {\n uniforms.iTime.value = t * 0.001;\n\n const lerpFactor = 0.1;\n mousePositionRef.current.x += (targetMouseRef.current.x - mousePositionRef.current.x) * lerpFactor;\n mousePositionRef.current.y += (targetMouseRef.current.y - mousePositionRef.current.y) * lerpFactor;\n\n const currentInfluence = uniforms.mouseInfluence.value;\n const targetInfluence = mouseInfluenceRef.current;\n uniforms.mouseInfluence.value += (targetInfluence - currentInfluence) * 0.05;\n\n uniforms.mousePosition.value = [mousePositionRef.current.x, mousePositionRef.current.y];\n\n renderer.render({ scene: mesh });\n animationFrameId = requestAnimationFrame(render);\n };\n\n animationFrameId = requestAnimationFrame(render);\n\n return () => {\n cancelAnimationFrame(animationFrameId);\n window.removeEventListener('resize', resize);\n if (mouseInteraction && containerRef.current) {\n containerRef.current.removeEventListener('mousemove', handleMouseMove);\n containerRef.current.removeEventListener('mouseenter', handleMouseEnter);\n containerRef.current.removeEventListener('mouseleave', handleMouseLeave);\n }\n renderer.gl.getExtension('WEBGL_lose_context')?.loseContext();\n containerRef.current?.removeChild(gl.canvas);\n };\n }, []);\n\n useEffect(() => {\n if (!uniformsRef.current) return;\n\n const hexToRgb = (hex: string): [number, number, number] => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? [parseInt(result[1], 16) / 255, parseInt(result[2], 16) / 255, parseInt(result[3], 16) / 255]\n : [1, 1, 1];\n };\n\n uniformsRef.current.enableRainbow.value = enableRainbow;\n uniformsRef.current.gridColor.value = hexToRgb(gridColor);\n uniformsRef.current.rippleIntensity.value = rippleIntensity;\n uniformsRef.current.gridSize.value = gridSize;\n uniformsRef.current.gridThickness.value = gridThickness;\n uniformsRef.current.fadeDistance.value = fadeDistance;\n uniformsRef.current.vignetteStrength.value = vignetteStrength;\n uniformsRef.current.glowIntensity.value = glowIntensity;\n uniformsRef.current.opacity.value = opacity;\n uniformsRef.current.gridRotation.value = gridRotation;\n uniformsRef.current.mouseInteraction.value = mouseInteraction;\n uniformsRef.current.mouseInteractionRadius.value = mouseInteractionRadius;\n }, [\n enableRainbow,\n gridColor,\n rippleIntensity,\n gridSize,\n gridThickness,\n fadeDistance,\n vignetteStrength,\n glowIntensity,\n opacity,\n gridRotation,\n mouseInteraction,\n mouseInteractionRadius\n ]);\n\n return
;\n};\n\nexport default RippleGrid;\n" } ], "registryDependencies": [],