Audio Visualiser_myWave

by SQShu

HTML

<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <title>My_Audio_Visualiser_SSQ</title>
    <link href="https://fonts.googleapis.com/css?family=Saira" rel="stylesheet">
    <link rel="stylesheet" href="style.css">
  </head>

  <body>
    <!-- partial:index.partial.html -->
    <div id="content">

      <label for="thefile" class="file"> Choose an audio file
        <input type="file" id="thefile" accept="audio/*" />
      </label>

      <audio id="audio" controls></audio>
      <div id="container"></div>
      <script id="vertex" type="x-shader/x-vertex">
        void main() {    
      gl_Position = vec4(position, 1.0); 
    }
</script>

      <script id="fragment" type="x-shader/x-vertex">
        precision mediump float;
	
uniform vec2 u_resolution;
uniform float u_time;
uniform vec2 u_mouse;
#define M_PI 3.14159265358979323846



void main() {

	vec2 uv = (gl_FragCoord.xy - u_resolution * 0.5) / u_resolution.yy;
    
    vec2 st = u_mouse.xy/u_resolution.xy;
    
    // Centerings 定位中心點
	uv += vec2(1.3, 1.0); 

	// Create one circle 創建一個圓 
	float circle = distance(uv, vec2(0.5)) * (abs(sin(u_time))/2.0+0.5); // radius 控制半徑
	float dm = abs(sin(u_time * M_PI));  // rate 控制跳動速率
	
    
    // Create light 創建光效
	vec3 light = vec3(0.5-tan(sin(circle*0.5+dm)), 0.5-acos(tan(circle*500.0+dm)), 0.0);
    
    
    // Mix hue&rgb 混合顏色和色相
	vec3 color1 = mix(light, vec3(8.0), 0.5-circle);   
	vec3 hue = mix(vec3(1.0, 1.0, 1.0), vec3(0.0, 0.0, 0.0), (st.y+abs(sin(u_time)))*0.5);
	vec3 color2 = mix(color1, hue, abs(uv.x-0.1));
	
    // Final shader  最後著色器渲染
	gl_FragColor = vec4(color1*color2, 0.5);
}
</script>
    </div>
    <!-- partial -->
    <script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
    <script src='https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js'></script>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.3/dat.gui.min.js'></script>
    <script...

CSS

:root {
  --bgColor: rgba(255, 255, 255, 1);
  --bgColorLight: rgb(141, 153, 174);
  --textColor: rgb(237, 242, 244);
  --textColorDark: rgb(0,0,0);
  --paperColor: rgb(43, 45, 66);
  --paperColorDark: rgb(43, 45, 66);
  --shadowColorFaint: rgba(0,0,0,0.2);
}

::selected {
  color: var(--textColorDark);
}

html,
body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  height: 100vh;
  width: 100vw;
  background: var(--bgColor);
  background: linear-gradient(135deg, var(--bgColor), var(--bgColorLight));
  color: var(--textColor);
  font-family: 'Saira', sans-serif;
  position: relative;
}

* {
  box-sizing: border-box;
  transition: all 0.12s cubic-bezier(0.42, 0.54, 0.22, 1.26);
}

#canvas {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

audio {
  position: fixed;
  left: 10px;
  bottom: -10px;
  width: calc(100% - 20px);
}

audio.active {
  bottom: 10px;
}

#thefile {
  width: 0.1px;
  height: 0.1px;
  opacity: 0;
  overflow: hidden;
  position: absolute;
  z-index: 1;
}

label.file {
  display: inline-block;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  padding: 1rem 2rem;
  border-radius: 120px;

  background: var(--paperColor);
  color: var(--textColor);
  font-size: 1.25em;
  font-weight: 700;
  box-shadow: 0 20px 60px var(--shadowColorFaint);

  cursor: pointer;
}


label.file:hover {
  background: var(--paperColorDark);
  transform: translate3d(-50%, -55%, 0);
}

label.file:active {
  background: var(--paperColorDark);
  transform: translate3d(-50%, -45%, 0);
}

label.file.normal {
  transform: translate3d(10%, 50%, 0);
  padding: 0.2rem 2rem;
  font-size: 1rem;
  top: 0;
  left: 0;
}

JavaScript

/* 1.13 把著色器顏色寫入了three.js中,留存的問題是:改寫的著色器無法正常顯示
    原因1: 著色器中存在沒有uniform的變量
    
   1.14 沒辦法,還是得自己寫新的著色器,尷尬了,明天看看能不能把mimic的Osc引入,把myWave給引入,不行就只能這樣了,唉
*/


function vertexShader() {
  return `
      varying vec3 vUv; 
      uniform float u_time;
      uniform vec2 u_mouse;
      uniform float myWave;

      
  
      void main() {
      vUv = position; 
  
        vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0)*abs(sin(u_time));
        gl_Position = projectionMatrix * modelViewPosition * abs(cos(myWave)); 
      }
    `
}

function fragmentShader() {
  return `
    uniform vec3 colorA; 
    uniform vec3 colorB; 
    uniform float u_time;
    uniform vec2 u_resolution;
    varying vec3 vUv;
    uniform float myWave;
    #define PI 3.14159265358979323846

    void main() {

     gl_FragColor = vec4(0.75-abs(cos((vUv.x+vUv.y))),sin(10.0), abs(sin(myWave)),1.0);
     

   
    }
`
}





//initialise simplex noise instance 創建一些簡單的噪音實例
var noise = new SimplexNoise();

// the main visualiser function 可視化的主函數
var vizInit = function() {

  var file = document.getElementById("thefile"); // 接收上傳文件
  var audio = document.getElementById("audio"); // 接收音頻
  var fileLabel = document.querySelector("label.file"); // 接收文件標籤

  // 加載&播放音頻
  document.onload = function(e) {
    console.log(e);
    audio.play();
    play();
  } // 文件路徑更改

  file.onchange = function() {
    fileLabel.classList.add('normal');
    audio.classList.add('active');
    var files = this.files;

    audio.src = URL.createObjectURL(files[0]);
    audio.load();
    audio.play();
    play();
  }

  // 播放函數,創建analyser
  function play() {
    var context = new AudioContext(); // 創建新的音頻Context
    var src = context.createMediaElementSource(audio); // 在context裡面創建src
    var analyser = context.createAnalyser(); // 在context中創建anapyser
    src.connect(analyser); // 連結analyser節點到src
    analyser.connect(context.destination); // 連結destination節點到analyser
    analyser.fftSize = 512; //...