1+ var noise = new SimplexNoise ( ) ;
2+ var vizInit = function ( ) {
3+
4+ var file = document . getElementById ( "thefile" ) ;
5+ var audio = document . getElementById ( "audio" ) ;
6+ var fileLabel = document . querySelector ( "label.file" ) ;
7+
8+ document . onload = function ( e ) {
9+ console . log ( e ) ;
10+ audio . play ( ) ;
11+ play ( ) ;
12+ }
13+ file . onchange = function ( ) {
14+ fileLabel . classList . add ( 'normal' ) ;
15+ audio . classList . add ( 'active' ) ;
16+ var files = this . files ;
17+
18+ audio . src = URL . createObjectURL ( files [ 0 ] ) ;
19+ audio . load ( ) ;
20+ audio . play ( ) ;
21+ play ( ) ;
22+ }
23+
24+ function play ( ) {
25+ var context = new AudioContext ( ) ;
26+ var src = context . createMediaElementSource ( audio ) ;
27+ var analyser = context . createAnalyser ( ) ;
28+ src . connect ( analyser ) ;
29+ analyser . connect ( context . destination ) ;
30+ analyser . fftSize = 512 ;
31+ var bufferLength = analyser . frequencyBinCount ;
32+ var dataArray = new Uint8Array ( bufferLength ) ;
33+ var scene = new THREE . Scene ( ) ;
34+ var group = new THREE . Group ( ) ;
35+ var camera = new THREE . PerspectiveCamera ( 45 , window . innerWidth / window . innerHeight , 0.1 , 1000 ) ;
36+ camera . position . set ( 0 , 0 , 100 ) ;
37+ camera . lookAt ( scene . position ) ;
38+ scene . add ( camera ) ;
39+
40+ var renderer = new THREE . WebGLRenderer ( { alpha : true , antialias : true } ) ;
41+ renderer . setSize ( window . innerWidth , window . innerHeight ) ;
42+
43+ var planeGeometry = new THREE . PlaneGeometry ( 800 , 800 , 20 , 20 ) ;
44+ var planeMaterial = new THREE . MeshLambertMaterial ( {
45+ color : 0x6904ce ,
46+ side : THREE . DoubleSide ,
47+ wireframe : true
48+ } ) ;
49+
50+ var plane = new THREE . Mesh ( planeGeometry , planeMaterial ) ;
51+ plane . rotation . x = - 0.5 * Math . PI ;
52+ plane . position . set ( 0 , 30 , 0 ) ;
53+ group . add ( plane ) ;
54+
55+ var plane2 = new THREE . Mesh ( planeGeometry , planeMaterial ) ;
56+ plane2 . rotation . x = - 0.5 * Math . PI ;
57+ plane2 . position . set ( 0 , - 30 , 0 ) ;
58+ group . add ( plane2 ) ;
59+
60+ var icosahedronGeometry = new THREE . IcosahedronGeometry ( 10 , 4 ) ;
61+ var lambertMaterial = new THREE . MeshLambertMaterial ( {
62+ color : 0xff00ee ,
63+ wireframe : true
64+ } ) ;
65+
66+ var ball = new THREE . Mesh ( icosahedronGeometry , lambertMaterial ) ;
67+ ball . position . set ( 0 , 0 , 0 ) ;
68+ group . add ( ball ) ;
69+
70+ var ambientLight = new THREE . AmbientLight ( 0xaaaaaa ) ;
71+ scene . add ( ambientLight ) ;
72+
73+ var spotLight = new THREE . SpotLight ( 0xffffff ) ;
74+ spotLight . intensity = 0.9 ;
75+ spotLight . position . set ( - 10 , 40 , 20 ) ;
76+ spotLight . lookAt ( ball ) ;
77+ spotLight . castShadow = true ;
78+ scene . add ( spotLight ) ;
79+
80+ scene . add ( group ) ;
81+
82+ document . getElementById ( 'out' ) . appendChild ( renderer . domElement ) ;
83+
84+ window . addEventListener ( 'resize' , onWindowResize , false ) ;
85+
86+ render ( ) ;
87+
88+ function render ( ) {
89+ analyser . getByteFrequencyData ( dataArray ) ;
90+
91+ var lowerHalfArray = dataArray . slice ( 0 , ( dataArray . length / 2 ) - 1 ) ;
92+ var upperHalfArray = dataArray . slice ( ( dataArray . length / 2 ) - 1 , dataArray . length - 1 ) ;
93+
94+ var overallAvg = avg ( dataArray ) ;
95+ var lowerMax = max ( lowerHalfArray ) ;
96+ var lowerAvg = avg ( lowerHalfArray ) ;
97+ var upperMax = max ( upperHalfArray ) ;
98+ var upperAvg = avg ( upperHalfArray ) ;
99+
100+ var lowerMaxFr = lowerMax / lowerHalfArray . length ;
101+ var lowerAvgFr = lowerAvg / lowerHalfArray . length ;
102+ var upperMaxFr = upperMax / upperHalfArray . length ;
103+ var upperAvgFr = upperAvg / upperHalfArray . length ;
104+
105+ makeRoughGround ( plane , modulate ( upperAvgFr , 0 , 1 , 0.5 , 4 ) ) ;
106+ makeRoughGround ( plane2 , modulate ( lowerMaxFr , 0 , 1 , 0.5 , 4 ) ) ;
107+
108+ makeRoughBall ( ball , modulate ( Math . pow ( lowerMaxFr , 0.8 ) , 0 , 1 , 0 , 8 ) , modulate ( upperAvgFr , 0 , 1 , 0 , 4 ) ) ;
109+
110+ group . rotation . y += 0.005 ;
111+ renderer . render ( scene , camera ) ;
112+ requestAnimationFrame ( render ) ;
113+ }
114+
115+ function onWindowResize ( ) {
116+ camera . aspect = window . innerWidth / window . innerHeight ;
117+ camera . updateProjectionMatrix ( ) ;
118+ renderer . setSize ( window . innerWidth , window . innerHeight ) ;
119+ }
120+
121+ function makeRoughBall ( mesh , bassFr , treFr ) {
122+ mesh . geometry . vertices . forEach ( function ( vertex , i ) {
123+ var offset = mesh . geometry . parameters . radius ;
124+ var amp = 7 ;
125+ var time = window . performance . now ( ) ;
126+ vertex . normalize ( ) ;
127+ var rf = 0.00001 ;
128+ var distance = ( offset + bassFr ) + noise . noise3D ( vertex . x + time * rf * 7 , vertex . y + time * rf * 8 , vertex . z + time * rf * 9 ) * amp * treFr ;
129+ vertex . multiplyScalar ( distance ) ;
130+ } ) ;
131+ mesh . geometry . verticesNeedUpdate = true ;
132+ mesh . geometry . normalsNeedUpdate = true ;
133+ mesh . geometry . computeVertexNormals ( ) ;
134+ mesh . geometry . computeFaceNormals ( ) ;
135+ }
136+
137+ function makeRoughGround ( mesh , distortionFr ) {
138+ mesh . geometry . vertices . forEach ( function ( vertex , i ) {
139+ var amp = 2 ;
140+ var time = Date . now ( ) ;
141+ var distance = ( noise . noise2D ( vertex . x + time * 0.0003 , vertex . y + time * 0.0001 ) + 0 ) * distortionFr * amp ;
142+ vertex . z = distance ;
143+ } ) ;
144+ mesh . geometry . verticesNeedUpdate = true ;
145+ mesh . geometry . normalsNeedUpdate = true ;
146+ mesh . geometry . computeVertexNormals ( ) ;
147+ mesh . geometry . computeFaceNormals ( ) ;
148+ }
149+
150+ audio . play ( ) ;
151+ } ;
152+ }
153+
154+ window . onload = vizInit ( ) ;
155+
156+ document . body . addEventListener ( 'touchend' , function ( ev ) { context . resume ( ) ; } ) ;
157+
158+
159+
160+
161+
162+ function fractionate ( val , minVal , maxVal ) {
163+ return ( val - minVal ) / ( maxVal - minVal ) ;
164+ }
165+
166+ function modulate ( val , minVal , maxVal , outMin , outMax ) {
167+ var fr = fractionate ( val , minVal , maxVal ) ;
168+ var delta = outMax - outMin ;
169+ return outMin + ( fr * delta ) ;
170+ }
171+
172+ function avg ( arr ) {
173+ var total = arr . reduce ( function ( sum , b ) { return sum + b ; } ) ;
174+ return ( total / arr . length ) ;
175+ }
176+
177+ function max ( arr ) {
178+ return arr . reduce ( function ( a , b ) { return Math . max ( a , b ) ; } )
179+ }
0 commit comments