一款3D可视化的本地音频播放特效,点击左上角的按钮选择一个本地音频,几秒钟加载后就会出现3D立体可视化的音频播放效果,非常的酷炫非常漂亮,如果不重新选择音频文件,将会单曲循环播放,喜欢的小伙伴们请收下吧。
页面的head部分需要设置好页面元素的样式,代码如下:
* {
margin: 0;
padding: 0;
}
body {
/* background: linear-gradient(-135deg, #FC656C, #11879E); */
overflow: hidden;
width: 100%;
height: 100%;
}
.color {
background: linear-gradient(-45deg, #48dfda, #20a0a4);
}
.black {
background: #000;
}
.wrapper .file {
position: absolute;
top: 20px;
left: 20px;
padding: 10px;
box-sizing: border-box;
border: 2px solid #fff;
letter-spacing: 0.01em;
color: #fff;
cursor: pointer;
transition: opacity .4s;
z-index: 2;
}
.wrapper .file:hover {
opacity: .8;
}
.wrapper .file input {
display: none;
}
.wrapper canvas {
vertical-align: bottom;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
页面的body部分,先引入一个JS插件three.js,然后设置一个文件选择的input,代码如下:
<div class="wrapper" id="wrapper">
<label class="file" for="file">
请选择本地音频文件
<input id="file" type="file">
</label>
</div>
页面的底部都是对音频播放可视化效果的处理,代码较多,这里仅贴出部分代码:
this.update = function () {
var offset = new THREE.Vector3();
// so camera.up is the orbit axis
var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
var quatInverse = quat.clone().inverse();
var lastPosition = new THREE.Vector3();
var lastQuaternion = new THREE.Quaternion();
return function update() {
var position = scope.object.position;
offset.copy( position ).sub( scope.target );
// rotate offset to "y-axis-is-up" space
offset.applyQuaternion( quat );
// angle from z-axis around y-axis
spherical.setFromVector3( offset );
if ( scope.autoRotate && state === STATE.NONE ) {
rotateLeft( getAutoRotationAngle() );
}
spherical.theta += sphericalDelta.theta;
spherical.phi += sphericalDelta.phi;
// restrict theta to be between desired limits
spherical.theta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, spherical.theta ) );
// restrict phi to be between desired limits
spherical.phi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, spherical.phi ) );
spherical.makeSafe();
spherical.radius *= scale;
// restrict radius to be between desired limits
spherical.radius = Math.max( scope.minDistance, Math.min( scope.maxDistance, spherical.radius ) );
// move target to panned location
scope.target.add( panOffset );
offset.setFromSpherical( spherical );
// rotate offset back to "camera-up-vector-is-up" space
offset.applyQuaternion( quatInverse );
position.copy( scope.target ).add( offset );
scope.object.lookAt( scope.target );
if ( scope.enableDamping === true ) {
sphericalDelta.theta *= ( 1 - scope.dampingFactor );
sphericalDelta.phi *= ( 1 - scope.dampingFactor );
} else {
sphericalDelta.set( 0, 0, 0 );
}
scale = 1;
panOffset.set( 0, 0, 0 );
// update condition is:
// min(camera displacement, camera rotation in radians)^2 > EPS
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
if ( zoomChanged ||
lastPosition.distanceToSquared( scope.object.position ) > EPS ||
8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {
scope.dispatchEvent( changeEvent );
lastPosition.copy( scope.object.position );
lastQuaternion.copy( scope.object.quaternion );
zoomChanged = false;
return true;
}
return false;
};
}();
系统已开启自动识别垃圾评论机制,识别到的自动封号,下载出错或者资源有问题请联系全栈客服QQ 1915635791