import * as THREE from 'three';
const renderer = new THREE.WebGLRenderer({ antialias: false });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0b0b14);
const camera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);
camera.position.set(0, 3.6, 4.8);
camera.lookAt(0, 0, 0);
const vertexShader = [
'varying vec2 vUv;',
'void main() {',
' vUv = uv;',
' gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
'}',
].join('\n');
const fragmentShader = [
'uniform float uTime;',
'varying vec2 vUv;',
'float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }',
'void main() {',
' vec2 cell = floor(vUv * 30.0);',
' float flick = hash(cell + floor(uTime * 8.0));',
' vec3 colA = vec3(1.0, 0.36, 0.48);',
' vec3 colB = vec3(0.37, 0.66, 1.0);',
' gl_FragColor = vec4(mix(colA, colB, step(0.5, flick)), 1.0);',
'}',
].join('\n');
const mesh = new THREE.Mesh(
new THREE.PlaneGeometry(7, 7),
new THREE.ShaderMaterial({ uniforms: { uTime: { value: 0 } }, vertexShader, fragmentShader })
);
mesh.rotation.x = -Math.PI / 2 + 0.05;
scene.add(mesh);
function resize() { renderer.setSize(innerWidth, innerHeight); camera.aspect = innerWidth / innerHeight; camera.updateProjectionMatrix(); }
addEventListener('resize', resize); resize();
renderer.setAnimationLoop((t) => {
mesh.material.uniforms.uTime.value = t * 0.001;
renderer.render(scene, camera);
});