Как я могу отображать этот анимированный холст на истинном фоне, за всем контентом, сохраняя его отзывчивым на распределительную высоту и прокрутку? "use client";
import React, { useRef, useEffect } from "react";
import { Renderer, Program, Mesh, Triangle, Color } from "ogl";
const vertexShader = `
attribute vec2 position;
attribute vec2 uv;
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4(position, 0.0, 1.0);
}
`;
const fragmentShader = `
precision highp float;
uniform float iTime;
uniform vec3 iResolution;
float random(vec2 st) {
return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);
}
float noise(vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
float a = random(i);
float b = random(i + vec2(1.0, 0.0));
float c = random(i + vec2(0.0, 1.0));
float d = random(i + vec2(1.0, 1.0));
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(a, b, u.x) +
(c - a) * u.y * (1.0 - u.x) +
(d - b) * u.x * u.y;
}
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
// Tiling
uv *= 4.0;
// Add time-based wobble for "expanding/contracting"
float t = iTime * 0.3;
vec2 movingUV = uv + vec2(sin(t + uv.y * 2.0), cos(t + uv.x * 2.0)) * 0.25;
// Use sharper contrast in noise
float n = noise(movingUV);
float wave = sin(n * 10.0 - t * 2.0) * 0.5 + 0.5;
// Emphasize darker textures
vec3 baseColor = vec3(0.04); // base dark
vec3 edgeGlow = vec3(0.13); // highlight lines
vec3 color = mix(baseColor, edgeGlow, wave * 0.2);
gl_FragColor = vec4(color, 1.0);
}
`;
export default function BackgroundCanvas() {
const containerRef = useRef(null);
const animationRef = useRef(0);
useEffect(() => {
const container = containerRef.current;
if (!container) return;
const renderer = new Renderer({ alpha: true });
const gl = renderer.gl;
gl.clearColor(0, 0, 0, 0);
Object.assign(gl.canvas.style, {
position: "absolute", //
top: "0",
left: "0",
width: "100%",
zIndex: "-50",
pointerEvents: "none",
});
container.appendChild(gl.canvas);
const geometry = new Triangle(gl);
const program = new Program(gl, {
vertex: vertexShader,
fragment: fragmentShader,
uniforms: {
iTime: { value: 0 },
iResolution: {
value: new Color(0, 0, 0),
},
},
});
const mesh = new Mesh(gl, { geometry, program });
const resize = () => {
const w = container.clientWidth;
const h = container.scrollHeight; //
renderer.setSize(w, h);
program.uniforms.iResolution.value.set(w, h, w / h);
};
window.addEventListener("resize", resize);
resize();
const render = (t: number) => {
program.uniforms.iTime.value = t * 0.001;
renderer.render({ scene: mesh });
animationRef.current = requestAnimationFrame(render);
};
animationRef.current = requestAnimationFrame(render);
return () => {
cancelAnimationFrame(animationRef.current);
window.removeEventListener("resize", resize);
if (container.contains(gl.canvas)) container.removeChild(gl.canvas);
};
}, []);
return (
ref={containerRef}
className="absolute top-0 left-0 w-full h-full -z-50 pointer-events-none"
/>
);
}
< /code>
и в моем майоне.import BackgroundCanvas from "./components/backgroundcanvas";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... hind-using