<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Balex Logo</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
canvas {
display: block;
width: 100%;
height: 100vh;
}
#logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
gap: 15px;
z-index: 10;
pointer-events: none;
}
.icon {
width: 70px;
height: 70px;
position: relative;
}
.arrow {
position: absolute;
width: 0;
height: 0;
border-style: solid;
}
.arrow1 {
top: 5px;
left: 10px;
border-width: 15px 0 15px 25px;
border-color: transparent transparent transparent #fff;
}
.arrow2 {
bottom: 5px;
right: 10px;
border-width: 15px 25px 15px 0;
border-color: transparent #fff transparent transparent;
}
.text {
font-size: 72px;
font-weight: 300;
color: #fff;
letter-spacing: -2px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="logo">
<div class="icon">
<div class="arrow arrow1"></div>
<div class="arrow arrow2"></div>
</div>
<div class="text">Balex</div>
</div>
<script>
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) {
alert('WebGL not supported');
}
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
gl.viewport(0, 0, canvas.width, canvas.height);
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// Vertex shader
const vertexShaderSource = `
attribute vec2 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main() {
gl_Position = vec4(a_position, 0.0, 1.0);
v_texCoord = a_texCoord;
}
`;
// Fragment shader
const fragmentShaderSource = `
precision highp float;
uniform vec2 u_resolution;
uniform float u_time;
void main() {
vec2 uv = (gl_FragCoord.xy - u_resolution * 0.5) / min(u_resolution.x, u_resolution.y);
// Dark teal background
vec3 col = vec3(0.0, 0.12, 0.12);
float numDiscs = 20.0;
for(float i = 0.0; i < 20.0; i++) {
float t = i / numDiscs;
// Spiral path
float angle = t * 3.14159 * 3.5 + u_time * 0.3;
float radius = (t - 0.5) * 1.6;
vec2 pos = vec2(
cos(angle) * radius * 0.9,
sin(angle) * radius * 0.4
);
float dist = length(uv - pos);
float discRadius = 0.13 + t * 0.03;
// Color gradient from cyan to yellow-green
vec3 startColor = vec3(0.2, 0.8, 0.8);
vec3 endColor = vec3(0.6, 0.9, 0.3);
vec3 discCol = mix(startColor, endColor, t);
// Glowing edge effect
float edge = abs(dist - discRadius);
float rim = smoothstep(0.02, 0.0, edge) * 1.5;
float glow = exp(-edge * 15.0) * 0.6;
float alpha = rim + glow;
col = mix(col, discCol, alpha * (0.9 - t * 0.4));
}
gl_FragColor = vec4(col, 1.0);
}
`;
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
return null;
}
return program;
}
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = createProgram(gl, vertexShader, fragmentShader);
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
const resolutionUniformLocation = gl.getUniformLocation(program, 'u_resolution');
const timeUniformLocation = gl.getUniformLocation(program, 'u_time');
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
-1, -1,
1, -1,
-1, 1,
-1, 1,
1, -1,
1, 1,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
function render(time) {
time *= 0.001;
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.enableVertexAttribArray(positionAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.uniform2f(resolutionUniformLocation, canvas.width, canvas.height);
gl.uniform1f(timeUniformLocation, time);
gl.drawArrays(gl.TRIANGLES, 0, 6);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
</script>
</body>
</html>“Create a "Balex Logo" component. Implement custom GLSL shaders for visual effects. Layout: Flexbox, full-viewport sizing. Interactivity: continuous animation loop, responsive resize handling.”