UNPKG

lightswind

Version:

A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.

133 lines (127 loc) 5.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const framer_motion_1 = require("framer-motion"); const vertexShaderSource = ` attribute vec4 a_position; void main() { gl_Position = a_position; } `; const fragmentShaderSource = ` precision mediump float; uniform vec2 iResolution; uniform float iTime; void mainImage(out vec4 fragColor, in vec2 fragCoord) { vec2 uv = (2.0 * fragCoord - iResolution.xy) / min(iResolution.x, iResolution.y); for(float i = 1.0; i < 8.0; i++) { uv.y += i * 0.1 / i * sin(uv.x * i * i + iTime * 0.5) * sin(uv.y * i * i + iTime * 0.5); } vec3 col; col.r = uv.y - 0.1; col.g = uv.y + 0.3; col.b = uv.y + 0.95; fragColor = vec4(col, 1.0); } void main() { mainImage(gl_FragColor, gl_FragCoord.xy); } `; const blurClassMap = { none: "backdrop-blur-none", sm: "backdrop-blur-sm", md: "backdrop-blur-md", lg: "backdrop-blur-lg", xl: "backdrop-blur-xl", "2xl": "backdrop-blur-2xl", "3xl": "backdrop-blur-3xl", }; function WaveBackground({ backdropBlurAmount = "sm", className = "", }) { const canvasRef = (0, react_1.useRef)(null); const containerRef = (0, react_1.useRef)(null); const isInView = (0, framer_motion_1.useInView)(containerRef); const visibilityRef = (0, react_1.useRef)(true); (0, react_1.useEffect)(() => { visibilityRef.current = isInView; }, [isInView]); (0, react_1.useEffect)(() => { const canvas = canvasRef.current; if (!canvas) return; const gl = canvas.getContext("webgl"); if (!gl) { console.error("WebGL not supported"); return; } const compileShader = (type, source) => { const shader = gl.createShader(type); if (!shader) return null; gl.shaderSource(shader, source); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { console.error("Shader compilation error:", gl.getShaderInfoLog(shader)); gl.deleteShader(shader); return null; } return shader; }; const vertexShader = compileShader(gl.VERTEX_SHADER, vertexShaderSource); const fragmentShader = compileShader(gl.FRAGMENT_SHADER, fragmentShaderSource); if (!vertexShader || !fragmentShader) return; const program = gl.createProgram(); if (!program) return; gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.error("Program linking error:", gl.getProgramInfoLog(program)); return; } gl.useProgram(program); const positionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW); const positionLocation = gl.getAttribLocation(program, "a_position"); gl.enableVertexAttribArray(positionLocation); gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0); const iResolutionLocation = gl.getUniformLocation(program, "iResolution"); const iTimeLocation = gl.getUniformLocation(program, "iTime"); let startTime = Date.now(); let animationFrameId; const render = () => { if (!visibilityRef.current) { animationFrameId = requestAnimationFrame(render); return; } const width = canvas.clientWidth; const height = canvas.clientHeight; canvas.width = width; canvas.height = height; // Ensure the program is used before setting uniforms (Critical for React Strict Mode) gl.useProgram(program); gl.viewport(0, 0, width, height); const currentTime = (Date.now() - startTime) / 1000; gl.uniform2f(iResolutionLocation, width, height); gl.uniform1f(iTimeLocation, currentTime); gl.drawArrays(gl.TRIANGLES, 0, 6); animationFrameId = requestAnimationFrame(render); }; render(); return () => { cancelAnimationFrame(animationFrameId); gl.deleteProgram(program); gl.deleteShader(vertexShader); gl.deleteShader(fragmentShader); gl.deleteBuffer(positionBuffer); }; }, []); const finalBlurClass = blurClassMap[backdropBlurAmount] || blurClassMap["sm"]; return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, className: `w-full max-w-screen h-full overflow-hidden ${className}`, children: [(0, jsx_runtime_1.jsx)("canvas", { ref: canvasRef, className: "absolute inset-0 w-full max-w-screen h-full overflow-hidden", style: { display: "block" } }), (0, jsx_runtime_1.jsx)("div", { className: `absolute inset-0 ${finalBlurClass}` })] })); } exports.default = WaveBackground; //# sourceMappingURL=wave-background.js.map