feat: improve background

This commit is contained in:
Dan Finch 2026-05-19 23:52:38 +02:00
parent a11f391556
commit 9a7bc30f7b
4 changed files with 54 additions and 27 deletions

View file

@ -1,3 +1,5 @@
// 100% VIBES
const canvas = document.getElementById('background');
const gl = canvas.getContext('webgl');
@ -21,6 +23,7 @@ void main() { gl_Position = vec4(a_pos, 0.0, 1.0); }
#extension GL_OES_standard_derivatives : enable
precision highp float;
uniform float u_time;
uniform float u_glitch;
uniform vec2 u_res;
#define COL_SKY_TOP vec3(0.04, 0.0, 0.12)
@ -56,20 +59,14 @@ float mountain(float x, float scale, float height, float offset) {
return m * height * sideMask;
}
float glitch(float y, float t) {
float gt = mod(t, 25.0);
float g1 = smoothstep(12.0, 12.05, gt) * smoothstep(12.25, 12.2, gt);
float g = g1;
float glitch(float y, float t, float g) {
if (g < 0.01) return 0.0;
float band = step(0.7, hash(vec2(floor(y * 30.0), floor(t * 20.0))));
float off = (hash(vec2(floor(y * 30.0), floor(t * 30.0))) - 0.5) * 0.06;
return off * band * g;
}
float glitchColor(float y, float t) {
float gt = mod(t, 25.0);
float g1 = smoothstep(12.0, 12.05, gt) * smoothstep(12.25, 12.2, gt);
float g = g1;
float glitchColor(float y, float t, float g) {
float band = step(0.6, hash(vec2(floor(y * 25.0), floor(t * 15.0))));
return band * g;
}
@ -79,7 +76,7 @@ void main() {
float aspect = u_res.x / u_res.y;
float t = u_time;
float gOff = glitch(uv.y, t);
float gOff = glitch(uv.y, t, u_glitch);
uv.x += gOff;
vec2 cuv = (uv - 0.5) * vec2(aspect, 1.0);
@ -170,7 +167,7 @@ void main() {
float vignette = 1.0 - dot(vc * 0.5, vc * 0.5);
col *= smoothstep(0.0, 0.7, vignette);
float gc = glitchColor(uv.y, t);
float gc = glitchColor(uv.y, t, u_glitch);
col.r += gc * 0.15;
col.b -= gc * 0.1;
@ -210,13 +207,52 @@ void main() {
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
const uTime = gl.getUniformLocation(prog, 'u_time');
const uGlitch = gl.getUniformLocation(prog, 'u_glitch');
const uRes = gl.getUniformLocation(prog, 'u_res');
const start = performance.now();
(function frame() {
gl.uniform1f(uTime, (performance.now() - start) / 1000);
const glitchDuration = 300;
let glitchStart = -glitchDuration;
let elapsed = 0;
let lastFrame = 0;
let raf = null;
document.addEventListener('click', function() {
glitchStart = performance.now();
}, true);
function glitchAmount(now) {
const age = now - glitchStart;
if (age < 0 || age > glitchDuration) return 0;
return Math.sin((age / glitchDuration) * Math.PI);
}
function frame(now) {
if (document.hidden) {
raf = null;
lastFrame = 0;
return;
}
if (lastFrame) {
elapsed += Math.min((now - lastFrame) / 1000, 0.1);
}
lastFrame = now;
gl.uniform1f(uTime, elapsed);
gl.uniform1f(uGlitch, glitchAmount(now));
gl.uniform2f(uRes, canvas.width, canvas.height);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(frame);
})();
raf = requestAnimationFrame(frame);
}
function startAnimation() {
if (!raf && !document.hidden) {
lastFrame = 0;
raf = requestAnimationFrame(frame);
}
}
document.addEventListener('visibilitychange', startAnimation);
startAnimation();
}