Spaces:
Sleeping
Sleeping
File size: 7,699 Bytes
6193995 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | (function () {
const canvas = document.getElementById('dm-shader-bg');
if (!canvas) return;
const gl = canvas.getContext('webgl');
if (!gl) {
console.warn('DataMind: WebGL not supported, shader background skipped.');
return;
}
// ββ Vertex Shader βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
const vsSource = `
attribute vec4 aVertexPosition;
void main() {
gl_Position = aVertexPosition;
}
`;
// ββ Fragment Shader β DataMind colour palette ββββββββββββββββββββββββββββββ
const fsSource = `
precision highp float;
uniform vec2 iResolution;
uniform float iTime;
const float overallSpeed = 0.15;
const float gridSmoothWidth = 0.015;
const float axisWidth = 0.05;
const float majorLineWidth = 0.025;
const float minorLineWidth = 0.0125;
const float majorLineFreq = 5.0;
const float minorLineFreq = 1.0;
const float scale = 5.0;
/* ββ Cyan accent #00d4ff ββ */
const vec4 lineColor = vec4(0.0, 0.831, 1.0, 1.0);
const float minLineWidth = 0.01;
const float maxLineWidth = 0.18;
const float lineSpeed = 1.0 * overallSpeed;
const float lineAmplitude = 1.0;
const float lineFrequency = 0.2;
const float warpSpeed = 0.2 * overallSpeed;
const float warpFrequency = 0.5;
const float warpAmplitude = 1.0;
const float offsetFrequency = 0.5;
const float offsetSpeed = 1.33 * overallSpeed;
const float minOffsetSpread = 0.6;
const float maxOffsetSpread = 2.0;
const int linesPerGroup = 16;
#define drawCircle(pos, radius, coord) \
smoothstep(radius + gridSmoothWidth, radius, length(coord - (pos)))
#define drawSmoothLine(pos, halfWidth, t) \
smoothstep(halfWidth, 0.0, abs(pos - (t)))
#define drawCrispLine(pos, halfWidth, t) \
smoothstep(halfWidth + gridSmoothWidth, halfWidth, abs(pos - (t)))
#define drawPeriodicLine(freq, width, t) \
drawCrispLine(freq / 2.0, width, abs(mod(t, freq) - (freq) / 2.0))
float random(float t) {
return (cos(t) + cos(t * 1.3 + 1.3) + cos(t * 1.4 + 1.4)) / 3.0;
}
float getPlasmaY(float x, float hFade, float offset) {
return random(x * lineFrequency + iTime * lineSpeed) * hFade * lineAmplitude + offset;
}
void main() {
vec2 fragCoord = gl_FragCoord.xy;
vec2 uv = fragCoord / iResolution.xy;
vec2 space = (fragCoord - iResolution.xy * 0.5) / iResolution.x * 2.0 * scale;
float hFade = 1.0 - (cos(uv.x * 6.28318) * 0.5 + 0.5);
float vFade = 1.0 - (cos(uv.y * 6.28318) * 0.5 + 0.5);
/* subtle warp */
space.y += random(space.x * warpFrequency + iTime * warpSpeed) * warpAmplitude * (0.5 + hFade);
space.x += random(space.y * warpFrequency + iTime * warpSpeed + 2.0) * warpAmplitude * hFade;
vec4 lines = vec4(0.0);
/* ββ Background gradient: #161a24 β #1a1a2e ββ */
vec4 bgColor1 = vec4(0.086, 0.102, 0.141, 1.0);
vec4 bgColor2 = vec4(0.102, 0.102, 0.180, 1.0);
for (int l = 0; l < linesPerGroup; l++) {
float nli = float(l) / float(linesPerGroup);
float offsetTime = iTime * offsetSpeed;
float offsetPos = float(l) + space.x * offsetFrequency;
float rand = random(offsetPos + offsetTime) * 0.5 + 0.5;
float halfWidth = mix(minLineWidth, maxLineWidth, rand * hFade) * 0.5;
float offset = random(offsetPos + offsetTime * (1.0 + nli))
* mix(minOffsetSpread, maxOffsetSpread, hFade);
float linePos = getPlasmaY(space.x, hFade, offset);
float line = drawSmoothLine(linePos, halfWidth, space.y) * 0.5
+ drawCrispLine(linePos, halfWidth * 0.15, space.y);
float circleX = mod(float(l) + iTime * lineSpeed, 25.0) - 12.0;
vec2 circlePos = vec2(circleX, getPlasmaY(circleX, hFade, offset));
float circle = drawCircle(circlePos, 0.01, space) * 4.0;
lines += (line + circle) * lineColor * rand;
}
vec4 fragColor = mix(bgColor1, bgColor2, uv.x);
fragColor *= vFade;
fragColor.a = 1.0;
fragColor += lines;
gl_FragColor = fragColor;
}
`;
// ββ Compile helpers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
function compileShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('Shader error:', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
function createProgram(gl, vs, fs) {
const prog = gl.createProgram();
gl.attachShader(prog, vs);
gl.attachShader(prog, fs);
gl.linkProgram(prog);
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
console.error('Program link error:', gl.getProgramInfoLog(prog));
return null;
}
return prog;
}
// ββ Build program ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
const vs = compileShader(gl, gl.VERTEX_SHADER, vsSource);
const fs = compileShader(gl, gl.FRAGMENT_SHADER, fsSource);
const program = createProgram(gl, vs, fs);
if (!program) return;
const posBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),
gl.STATIC_DRAW
);
const aPos = gl.getAttribLocation(program, 'aVertexPosition');
const uRes = gl.getUniformLocation(program, 'iResolution');
const uTime = gl.getUniformLocation(program, 'iTime');
// ββ Resize βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
function resize() {
const parent = canvas.parentElement;
canvas.width = parent ? parent.offsetWidth : window.innerWidth;
canvas.height = parent ? parent.offsetHeight : window.innerHeight;
gl.viewport(0, 0, canvas.width, canvas.height);
}
window.addEventListener('resize', resize);
resize();
// ββ Render loop ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
const startTime = Date.now();
function render() {
// Stop rendering if canvas is no longer visible (dashboard loaded)
if (!canvas.isConnected || canvas.offsetParent === null) return;
const t = (Date.now() - startTime) / 1000;
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.uniform2f(uRes, canvas.width, canvas.height);
gl.uniform1f(uTime, t);
gl.bindBuffer(gl.ARRAY_BUFFER, posBuffer);
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPos);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
})();
|