|
|
function _class_call_check(instance, Constructor) { |
|
|
if (!(instance instanceof Constructor)) { |
|
|
throw new TypeError("Cannot call a class as a function"); |
|
|
} |
|
|
} |
|
|
function _defineProperties(target, props) { |
|
|
for(var i = 0; i < props.length; i++){ |
|
|
var descriptor = props[i]; |
|
|
descriptor.enumerable = descriptor.enumerable || false; |
|
|
descriptor.configurable = true; |
|
|
if ("value" in descriptor) descriptor.writable = true; |
|
|
Object.defineProperty(target, descriptor.key, descriptor); |
|
|
} |
|
|
} |
|
|
function _create_class(Constructor, protoProps, staticProps) { |
|
|
if (protoProps) _defineProperties(Constructor.prototype, protoProps); |
|
|
if (staticProps) _defineProperties(Constructor, staticProps); |
|
|
return Constructor; |
|
|
} |
|
|
function _instanceof(left, right) { |
|
|
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { |
|
|
return !!right[Symbol.hasInstance](left); |
|
|
} else { |
|
|
return left instanceof right; |
|
|
} |
|
|
} |
|
|
import * as THREE from 'three'; |
|
|
|
|
|
export var WaveformVisualizer = function() { |
|
|
"use strict"; |
|
|
function WaveformVisualizer(scene, analyser, canvasWidth, canvasHeight) { |
|
|
_class_call_check(this, WaveformVisualizer); |
|
|
this.scene = scene; |
|
|
this.analyser = analyser; |
|
|
this.mesh = null; |
|
|
this.bufferLength = this.analyser.size; |
|
|
this.dataArray = new Float32Array(this.bufferLength); |
|
|
this.smoothedDataArray = new Float32Array(this.bufferLength); |
|
|
|
|
|
this.smoothingFactor = 0.4; |
|
|
this.width = canvasWidth * 0.8; |
|
|
this.height = 450; |
|
|
this.yPosition = 0; |
|
|
this.thickness = 30.0; |
|
|
this.currentColor = new THREE.Color('#7B4394'); |
|
|
this.targetColor = new THREE.Color('#7B4394'); |
|
|
this.uniforms = { |
|
|
solidColor: { |
|
|
value: this.currentColor |
|
|
} |
|
|
}; |
|
|
this._createVisualizer(); |
|
|
} |
|
|
_create_class(WaveformVisualizer, [ |
|
|
{ |
|
|
key: "_createVisualizer", |
|
|
value: function _createVisualizer() { |
|
|
var material = new THREE.ShaderMaterial({ |
|
|
uniforms: this.uniforms, |
|
|
vertexShader: "\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ", |
|
|
fragmentShader: "\n uniform vec3 solidColor;\n void main() {\n gl_FragColor = vec4(solidColor, 0.9);\n }\n ", |
|
|
transparent: true, |
|
|
side: THREE.DoubleSide |
|
|
}); |
|
|
var geometry = new THREE.BufferGeometry(); |
|
|
var positions = new Float32Array(this.bufferLength * 2 * 3); |
|
|
var uvs = new Float32Array(this.bufferLength * 2 * 2); |
|
|
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); |
|
|
geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2)); |
|
|
var indices = []; |
|
|
for(var i = 0; i < this.bufferLength - 1; i++){ |
|
|
var p1 = i * 2; |
|
|
var p2 = p1 + 1; |
|
|
var p3 = (i + 1) * 2; |
|
|
var p4 = p3 + 1; |
|
|
indices.push(p1, p2, p3); |
|
|
indices.push(p2, p4, p3); |
|
|
} |
|
|
geometry.setIndex(indices); |
|
|
this.mesh = new THREE.Mesh(geometry, material); |
|
|
this.scene.add(this.mesh); |
|
|
this.updatePosition(window.innerWidth, window.innerHeight); |
|
|
} |
|
|
}, |
|
|
{ |
|
|
|
|
|
key: "update", |
|
|
value: function update() { |
|
|
if (!this.analyser || !this.mesh) return; |
|
|
|
|
|
this.currentColor.lerp(this.targetColor, 0.05); |
|
|
var newArray = this.analyser.getValue(); |
|
|
if (_instanceof(newArray, Float32Array)) { |
|
|
this.dataArray.set(newArray); |
|
|
} |
|
|
var positions = this.mesh.geometry.attributes.position.array; |
|
|
var uvs = this.mesh.geometry.attributes.uv.array; |
|
|
var startX = -this.width / 2; |
|
|
var xStep = this.width / (this.bufferLength - 1); |
|
|
var halfThickness = this.thickness / 2; |
|
|
for(var i = 0; i < this.bufferLength; i++){ |
|
|
|
|
|
this.smoothedDataArray[i] = this.smoothingFactor * this.dataArray[i] + (1 - this.smoothingFactor) * this.smoothedDataArray[i]; |
|
|
var x = startX + i * xStep; |
|
|
var y = this.yPosition + this.smoothedDataArray[i] * this.height; |
|
|
|
|
|
var vertexIndex = i * 2 * 3; |
|
|
positions[vertexIndex] = x; |
|
|
positions[vertexIndex + 1] = y + halfThickness; |
|
|
positions[vertexIndex + 2] = 2; |
|
|
positions[vertexIndex + 3] = x; |
|
|
positions[vertexIndex + 4] = y - halfThickness; |
|
|
positions[vertexIndex + 5] = 2; |
|
|
|
|
|
var uvIndex = i * 2 * 2; |
|
|
uvs[uvIndex] = i / (this.bufferLength - 1); |
|
|
uvs[uvIndex + 1] = 1.0; |
|
|
uvs[uvIndex + 2] = i / (this.bufferLength - 1); |
|
|
uvs[uvIndex + 3] = 0.0; |
|
|
} |
|
|
this.mesh.geometry.attributes.position.needsUpdate = true; |
|
|
this.mesh.geometry.attributes.uv.needsUpdate = true; |
|
|
this.mesh.geometry.computeBoundingSphere(); |
|
|
} |
|
|
}, |
|
|
{ |
|
|
key: "updateColor", |
|
|
value: function updateColor(newColor) { |
|
|
if (this.uniforms) { |
|
|
this.targetColor.set(newColor); |
|
|
} |
|
|
} |
|
|
}, |
|
|
{ |
|
|
|
|
|
key: "updatePosition", |
|
|
value: function updatePosition(canvasWidth, canvasHeight) { |
|
|
this.width = canvasWidth * 0.8; |
|
|
this.yPosition = -canvasHeight / 2 + 250; |
|
|
} |
|
|
}, |
|
|
{ |
|
|
|
|
|
key: "dispose", |
|
|
value: function dispose() { |
|
|
if (this.mesh) { |
|
|
this.scene.remove(this.mesh); |
|
|
if (this.mesh.geometry) this.mesh.geometry.dispose(); |
|
|
if (this.mesh.material) this.mesh.material.dispose(); |
|
|
} |
|
|
} |
|
|
} |
|
|
]); |
|
|
return WaveformVisualizer; |
|
|
}(); |