packages feed

hylogen-0.1.0.4: app/index.html

<!DOCTYPE html>
<html>
  <head>
    <title>HYLOGEN</title>
    <style>
     html, body {
         width: 100%;
         height: 100%;
         margin: 0;
         padding: 0;
         overflow: hidden;
     }
     body {
         display: flex;
         justify-content: center;
         align-items: center;
     }
     #canvas {
         width: 100vmax;
         height: 100vmax;
         background: white;
     }
     #landing {
         width: 100vw;
         height: 100vh;
         position: fixed;
         right: 0;
         top: 0;
         color: white;
         display: flex;
         justify-content: center;
         align-items: center;
         font-family: arial;
         line-height: 10em;
         pointer-events: none;
     }
     #bg {
         background: black;
         width: 100vw;
         height: 100vh;
         position: fixed;
         right: 0;
         top: 0;
         pointer-events: none;
     }

     #title {
         text-transform: uppercase;
         font-style: italic;
         font-weight: bold;
         font-size: 15vw;
         letter-spacing: 0.1em;
         text-shadow: 0 0 0.2em white;
         pointer-events: auto;
     }
     @keyframes fadeOut {
         0% {opacity: 1;}
         100% {opacity: 0;} 
     } 
     .removing {
         -webkit-animation: fadeOut 1000ms;
         -moz-animation: fadeOut 1000ms;
         animation: fadeOut 1000ms;
     }
     a {
         text-decoration: inherit;
     }

     a:visited {
         color: inherit;
     }
    </style>
  </head>
  <body>
    <div id="bg"> </div>
    <div id="landing">
      <div id="title">
        <a href="https://github.com/sleexyz/hylogen">
          Hylogen
        </a>
      </div>
    </div>

    <canvas id="canvas"></canvas>
    <script>
const vsSource = `
attribute vec3 aPosition;
varying vec3 uv;
void main() {
  gl_Position = vec4(aPosition, 1.0);
  uv = aPosition;
}
`;

const initialFsSource = `
precision mediump float;
uniform float time;
uniform vec3 mouse;
const float PI = 3.141592653589793238462643383;
varying vec3 uv;

void main() {
    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
`;


function loadProgram (gl, state, vsSource, fsSource) {

    // compileShader :: (gl, source, shaderType) -> Shader
    // throws Error on compilation error

    function compileShader (gl, source, shaderType) {
        //assert(shaderType === gl.FRAGMENT_SHADER || shaderType === g.VERTEXT_SHADER);

        let shader = gl.createShader(shaderType);

        gl.shaderSource(shader, source);
        gl.compileShader(shader);


        let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
        if (!success) {
            throw "could not compile shader:" + gl.getShaderInfoLog(shader);
        }

        return shader;
    };



    let vs = compileShader(gl, vsSource, gl.VERTEX_SHADER);
    let fs = compileShader(gl, fsSource, gl.FRAGMENT_SHADER);


    let program = gl.createProgram();

    gl.attachShader(program, vs);
    gl.attachShader(program, fs);

    gl.linkProgram(program);

    let success = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (!success) {
        throw ("program failed to link:" + gl.getProgramInfoLog(program));
    }

    gl.useProgram(program);


    // Create a square as a strip of two triangles.
    gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -1,1,0, 1,1,0, -1,-1,0, 1,-1,0 ]), gl.STATIC_DRAW);

    // Assign attribute aPosition to each of the square's vertices.
    gl.aPosition = gl.getAttribLocation(program, "aPosition");
    gl.enableVertexAttribArray(gl.aPosition);
    gl.vertexAttribPointer(gl.aPosition, 3, gl.FLOAT, false, 0, 0);

    // remember the address within the fragment shader of each of my uniforms variables
    gl.time = gl.getUniformLocation(program, "time");
    gl.mouse = gl.getUniformLocation(program, "mouse");
    gl.audio = gl.getUniformLocation(program, "audio");

    draw(gl, state);

    if (state.animationFrameRequest === null) {
        state.animationFrameRequest = requestAnimationFrame(() => animate(gl, state));
    }
}

function draw (gl, state) {

    gl.uniform1f(gl.time, (new Date().getTime() / 1000 - state.time0));
    gl.uniform3f(gl.mouse, state.mouse.x, state.mouse.y, state.mouse.z);
    gl.uniform4f(gl.audio, state.audio.low, state.audio.mid, state.audio.upper, state.audio.high);

    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
};

function animate (gl, state) {
    draw(gl, state);
    state.animationFrameRequest = requestAnimationFrame(() => animate(gl, state));
};



function setupState (state, canvas){
    state.animationFrameRequest = null;

    state.time0 = new Date() / 1000;


    function setMouse (event, z) {
        let r = event.target.getBoundingClientRect();
        state.mouse.x = (event.clientX - r.left) / (r.right - r.left) * 2 -1;
        state.mouse.y = (event.clientY - r.bottom) / (r.top - r.bottom) * 2 - 1;

        if (z !== undefined) {
            state.mouse.z = z;
        }
    };
    canvas.onmousedown = (event) => setMouse(event, 1);
    canvas.onmousemove = (event) => setMouse(event);
    canvas.onmouseup = (event) => setMouse(event, 0);
    state.mouse = {x: 0, y: 0, z: 0};


    state.audio = {low: 0.0, mid: 0.0, upper: 0.0, high: 0.0};
    state.audioAgain = null;
    navigator.mediaDevices.getUserMedia( {audio: true})
      .then((stream) => {
        let audioCtx = new (window.AudioContext || window.webkitAudioContext)();
        let source = audioCtx.createMediaStreamSource(stream);
        let analyser = audioCtx.createAnalyser();
        source.connect(analyser);

        analyser.fftSize = 512;
        let bufferLength = analyser.frequencyBinCount;
        let dataArray = new Uint8Array(bufferLength);


        function toAudio() {
          state.audioAgain = requestAnimationFrame(toAudio);
          analyser.getByteFrequencyData(dataArray);

            // Taken from The_Force
            let k = 0, f = 0.0;
            let a = 5, b = 11, c = 24, d = bufferLength, i = 0;

            for(; i < a; i++) {
                f += dataArray[i];
            }

            f *= .2; // 1/(a-0)
            f *= .003921569; // 1/255
            state.audio.low = f;

            f = 0.0;
            for(; i < b; i++) {
                f += dataArray[i];
            }

            f *= .166666667; // 1/(b-a)
            f *= .003921569; // 1/255
            state.audio.mid = f;

            f = 0.0;
            for(; i < c; i++) {
                f += dataArray[i];
            }

            f *= .076923077; // 1/(c-b)
            f *= .003921569; // 1/255
            state.audio.upper = f;

            f = 0.0;
            for(; i < d; i++) {
                f += dataArray[i];
            }
            f *= .00204918; // 1/(d-c)
            f *= .003921569; // 1/255
            state.audio.high = f;
        };

        toAudio();

      })
      .catch((err) => {console.log(err);});

}




// stateful variables

const canvas = document.getElementById("canvas");
canvas.width = Math.max(window.innerHeight, window.innerWidth);
canvas.height = Math.max(window.innerHeight, window.innerWidth);

const gl = canvas.getContext("webgl");

const state = {};

setupState(state, canvas);


loadProgram (gl, state,  vsSource, initialFsSource);


function fadeOut(elem) {
    elem.className = "removing";
    window.setTimeout(function() {
        elem.remove();
    }, 1000);
}

function connectToHylogen() {
    const wsConn = new WebSocket("ws://localhost:8080/");

    wsConn.onopen = function() {
        const landing = document.getElementById("landing");
        if (landing) {
            fadeOut(document.getElementById("bg"));
            window.setTimeout(() => {fadeOut(landing);}, 500);
        }
        console.log('websocket opened');

    };

    wsConn.onclose = function() {
        console.log('websocket closed');
        window.setTimeout(connectToHylogen, 100);
    };

    wsConn.onmessage = function (m) {
        console.log(m.data);
        loadProgram(gl, state,  vsSource, m.data);
    };
}

connectToHylogen();
    </script>
  </body>
</html>