three实现三维粒子跟随音乐跳动音频可视化效果代码
代码语言:html
所属分类:三维
代码描述:three实现三维粒子跟随音乐跳动音频可视化效果代码
代码标签: three 三维 粒子 跟随 音乐 跳动 音频 可视化
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
html, body {
margin: 0;
overflow: hidden;
font-family: sans-serif;
background: #13091B;
height: 100%;
}
#three-container {
position: absolute;
left: 0;
top: 0;
}
.container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.play-btn {
color: #13091B;
background: #007A99;
display: inline-block;
padding: 16px 48px;
font-size: 18px;
cursor: pointer;
border-radius: 4px;
letter-spacing: 0.1em;
z-index: 1;
}
</style>
</head>
<body >
<audio id="song" src="" style="display:none;"></audio>
<div class="container">
<div class="play-btn">PLAY</div>
</div>
<div id="three-container"></div>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.72.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.72.js"></script>
<script >
var mContainer;
var mCamera, mRenderer;
var mControls;
var mShadowColor = 0x13091B; //0x1B0914
var mScene;
var mLight;
var mLight2;
var mLight3;
var mUseAA = true;
var mParticleCount = 250000;
var mParticleSystem;
var mDuration;
var mPathLength = 32;
var mAudioElement = document.getElementById('song');
var mAnalyser;
var mPlayBtn = document.querySelector('.play-btn');
var mPlayBtnContainer = document.querySelector('.container');
mPlayBtn.addEventListener('click', function () {
mAnalyser.context.resume().then(() => {
console.log('Playback resumed successfully');
});
mPlayBtnContainer.style.display = 'none';
mAudioElement.currentTime = 0;
mAudioElement.play();
mCamera.position.set(0, 0, 1200);
});
mAudioElement.addEventListener('ended', function () {
mPlayBtnContainer.style.display = 'flex';
});
window.onload = function () {
init();
};
function init() {
initAudio();
initTHREE();
initControls();
initParticleSystem();
requestAnimationFrame(tick);
window.addEventListener('resize', resize, false);
}
function initAudio() {
mAudioElement.crossOrigin = "anonymous";
mAudioElement.src = '//repo.bfw.wiki/bfwrepo/sound/63e1f2ab02799.mp3';
mAnalyser = new SpectrumAnalyzer(mPathLength * 0.5, 0.80);
mAnalyser.setSource(mAudioElement);
}
function initTHREE() {
mRenderer = new THREE.WebGLRenderer({ antialias: mUseAA });
mRenderer.setSize(window.innerWidth, window.innerHeight);
//mRenderer.setClearColor(0xffffff);
mRenderer.setClearColor(mShadowColor);
mContainer = document.getElementById('three-container');
mContainer.appendChild(mRenderer.domElement);
mCamera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 5000);
mCamera.position.set(0, 0, 1200);
mScene = new THREE.Scene();
mLight = new THREE.PointLight(0xffffff, 1, 1200, 2);
mLight.position.set(0, 0, 0);
mScene.add(mLight);
mLight2 = new THREE.DirectionalLight(0xFF311F, 0.25);
mLight2.position.set(0, 1, 1);
mScene.add(mLight2);
mLight3 = new THREE.DirectionalLight(0x007A99, 0.25);
mLight3.position.set(0, 1, -1);
mScene.add(mLight3);
}
function initControls() {
mControls = new THREE.OrbitControls(mCamera, mRenderer.domElement);
mControls.autoRotate = true;
mControls.enableZoom = true;
mControls.enablePan = false;
mControls.constraint.minDistance = 10;
mControls.constraint.maxDistance = 1200;
mControls.constraint.minPolarAngle = Math.PI * 0.4;
mControls.constraint.maxPolarAngle = Math.PI * 0.6;
}
function initParticleSystem() {
var prefabGeometry = new THREE.PlaneGeometry(4, 4);
var bufferGeometry = new THREE.BAS.PrefabBufferGeometry(prefabGeometry, mParticleCount);
//bufferGeometry.computeVertexNormals();
// generate additional geometry data
var aDelayDuration = bufferGeometry.createAttribute('aDelayDuration', 2);
var aPivot = bufferGeometry.createAttribute('aPivot', 3);
var aAxisAngle = bufferGeometry.createAttribute('aAxisAngle', 4);
var aColor = bufferGeometry.createAttribute('color', 3);
var i, j, offset;
// buffer time offset
var delay;
var duration;
var prefabDelay = 0.00015;
var vertexDelay = 0.0175;
var minDuration = 32.0;
var maxDuration = 56.5;
mDuration = maxDuration + prefabDelay * mParticleCount + vertexDelay * prefabGeometry.vertices.length;
for (i = 0, offset = 0; i < mParticleCount; i++) {
delay = i * prefabDelay;
duration = THREE.Math.randFloat(minDuration, maxDuration);
for (j = 0; j < prefabGeometry.vertices.length; j++) {
aDelayDuration.array[offset++] = delay + j * vertexDelay;
aDelayDuration.array[offset++] = duration;
}
}
// buffer pivot
var pivot = new THREE.Vector3();
for (i = 0, offset = 0; i < mParticleCount; i++) {
pivot.x = THREE.Math.randFloat(0, 2);
pivot.y = THREE.Math.randFloat(0, 2);
pivot.z = THREE.Math.randFloat(0, 2);
for (j = 0; j < prefabGeometry.vertices.length; j++) {
aPivot.array[offset++] = pivot.x;
aPivot.array[offset++] = pivot.y;
aPivot.array[offset++] = pivot.z;
}
}
// buffer axis angle
var axis = new THREE.Vector3();
var angle = 0;
for (i = 0, offset = 0; i < mParticleCount; i++) {
axis.x = THREE.Math.randFloatSpread(2);
axis.y = THREE.Math.randFloatSpread(2);
axis.z = THREE.Math.randFloatSpread(2);
axis.normalize();
angle = Math.PI * THREE.Math.randInt(48, 64);
for (j = 0; j < prefabGeometry.vertices.length; j++) {
aAxisAngle.array[offset++] = axis.x;
aAxisAngle.array[offset++] = axis.y;
aAxisAngle.array[offset++] = axis.z;
aAxisAngle.array[offset++] = angle;
}
}
// buffer color
var color = new THREE.Color();
var h, s, l;
for (i = 0, offset = 0; i < mParticleCount; i++) {
//h = i / mParticleCount;
h = THREE.Math.randFloat(0.5, 1.00);
s = THREE.Math.randFloat(0.5, 0.75);
l = THREE.Math.randFloat(0.25, 0.5);
color.setHSL(h, s, l);
for (j = 0; j < prefabGeometry.vertices.length; j++) {
aColor.array[offset++] = color.r;
aColor.array[offset++] = color.g;
aColor.array[offset++] = color.b;
}
}
// buffer spline (uniform)
var pathArray = [];
var radiusArray = [];
var length = mPathLength;
var x, y, z;
for (i = 0; i < length; i++) {
if (!i) {
x = 0;
y = -1400;
z = 0;
} else
if (!(i - length + 1)) {
x = 0;
y = 1200;
z = 0;
} else
{
x = THREE.Math.randFloatSpread(600);
y = -400 + 800 / length * i + THREE.Math.randFloatSpread(200);
z = THREE.Math.randFloatSpread(600);
}
pathArray.push(x, y, z);
radiusArray.push(0);
}
var material = new THREE.BAS.PhongAnimationMaterial(
// custom parameters & THREE.MeshPhongMaterial parameters
{
vertexColors: THREE.VertexColors,
shading: THREE.FlatShading,
side: THREE.DoubleSide,
defines: {
PATH_LENGTH: pathArray.length / 3 },
uniforms: {
uTime: { type: 'f', value: 0 },
uPath: { type: 'fv', value: pathArray },
uRadius: { type: 'fv1', value: radiusArray },
uRoundness: { type: 'v2', value: new THREE.Vector2(2, 2) } },
shaderFunctions: [
THREE.BAS.ShaderChunk['quaternion_rotation'],
THREE.BAS.ShaderChunk['catmull-rom'],
THREE.BAS.ShaderChunk['ease_in_out_cubic']],
shaderParameters: [
'uniform float uTime;',
'uniform vec3 uPath[PATH_LENGTH];',
'uniform float uRadius[PATH_LENGTH];',
'uniform vec2 uRoundness;',
'attribute vec2 aDelayDuration;',
'attribute vec3 aPivot;',
'attribute vec4 aAxisAngle;'],
shaderVertexInit: [
'float tDelay = aDelayDuration.x;',
'float tDuration = aDelayDuration.y;',
'float tTime = clamp(uTime - tDelay, 0.0, tDuration);',
'float tProgress = tTime / tDuration;',
'float angle = aAxisAngle.w * tProgress;',
'vec4 tQuat = quatFromAxisAngle(aAxisAngle.xyz, angle);'],
shaderTransformNormal: [
'objectNormal = rotateVector(tQuat, objectNormal);'],
shaderTransformPosition: [
'float tMax = float(PATH_LENGTH - 1);',
'float tPoint = tMax * tProgress;',
'float tIndex = floor(tPoint);',
'float tWeight = tPoint - tIndex;',
'int i0 = int(max(0.0, tIndex - 1.0));',
'int i1 = int(tIndex);',
'int i2 = int(min(tIndex + 1.0, tMax));',
'int i3 = int(min(tIndex + 2.0, tMax));',
'vec3 p0 = uPath[i0];',
'vec3 p1 = uPath[i1];'.........完整代码请登录后点击上方下载按钮下载查看
网友评论0