packages feed

hylogen-0.1.0.5: 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;

       function onAccept (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();
       }
       function onFail(e) {
         console.error(e);
       }
       navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
       navigator.getUserMedia({audio: true}, onAccept, onFail);
     }




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