SuperShipped // Item 15

SNIPPET VIEW

Live Render

HTML CODE

<!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>

AI PROMPT

Create a "Balex Logo" component. Implement custom GLSL shaders for visual effects. Layout: Flexbox, full-viewport sizing. Interactivity: continuous animation loop, responsive resize handling.