效果展示
HTML代码如下
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link rel="stylesheet" href="./css/music.css" />
</head>
<body>
<div class="progress">
<div class="progress2"> </div>
</div>
<div class="btnarea">
<div class="line1">
<div class="arc1 btn">轻柔</div>
</div>
<div class="line2">
<div class="arc2 btn">节奏</div>
</div>
<div class="line3">
<div class="arc3 btn">DJ</div>
</div>
<div class="line4">
<div class="arc4 btn">纯音乐</div>
</div>
<div class="line5">
<div class="arc5" id="stop_btn">停止</div>
</div>
</div>
<div class="div1">
<ul class="oUl">
<li>
<img src="./img/1-1.png">
</li>
<li>
<img src="./img/2-2.png">
</li>
<li>
<img src="./img/3-3.png">
</li>
<li>
<img src="./img/4-4.png">
</li>
<li>
<img src="./img/5-5.png">
</li>
<li>
<img src="./img/6-6.png">
</li>
<li>
<img src="./img/7-7.png">
</li>
</ul>
</div>
<script src="./js/mTween.js"></script>
<script src="./js/music.js"></script>
</body>
</html>
如何实现?
JS代码
//dom获取上面的按钮列表,下面的手机列表,暂停按钮等
let oUlElement = document.querySelector('.oUl')
let imgElements= [...oUlElement.querySelectorAll('img')]
let btnElements = [...document.querySelectorAll('.btn')]
let stopBtn = document.querySelector('#stop_btn')
//初始化的每一张图片的位置,0-1之间的值,0为最低为,1为最高位
let initRatio = [1, .4 , 0, .4, .6, .4, 0]
//为0时的最低值
let bassRatioPosition = oUlElement.clientHeight *.8
// 随机颜色数组
let colors = [
'#ff5f5b',
'#ffb66e',
'#ffd96d',
'#e8f898',
'#8cf6f3',
'#92aef0',
'#b897e4'
]
//初始化已选颜色和音乐列表
let color = ''
let musicList = [
'./resource/mo.mp3',
'./resource/Rihanna - Only Girl (In The World).mp3',
'./resource/Remix.mp3',
'./resource/Neptune Illusion Dennis Kuo .mp3'
]
//初始化音频元素以及
let audio = null
let audioContext = null
let sourceNode = null
let analyser = null
//目前激活的按钮
let currentBtn = null
// 使用css3的translate,添加某个元素上即上升到顶部的动画的css
imgElements.forEach( (img,index) => {
let {x} = img.getBoundingClientRect()
img._centerPointer = {
x: x + img.width / 2
}
setTransform(img, 'translateY', getTranslateByRatio(initRatio[index]))
})
function getTranslateByRatio(ratio){
return (1 - ratio) * bassRatioPosition
}
//onmouseover,leave完成鼠标移动的动画
//mTween库动态加上translate样式
oUlElement.onmouseover = function({clientX}){
let vals = imgElements.map((img, index) => {
return 1 - Math.abs(clientX - img._centerPointer.x) / window.innerWidth
})
animatePhone(vals)
}
oUlElement.onmouseleave = function(){
animatePhone(initRatio);
}
//遍历手机的位置
function animatePhone(ratio){
imgElements.forEach((img, index) => {
mTween.stop(img)
mTween({
el:img,
attr:{
translateY: getTranslateByRatio(ratio[index])
}
})
} )
}
// 按钮激活时,动态添加样式
btnElements.forEach( (btn, index) => {
btn.onclick = function() {
color = colors[Math.floor(Math.random() * colors.length)];
currentBtn && mTween.stop(currentBtn);
btnElements.forEach(btn => btn.style = '');
btn.style.backgroundColor = color;
btn.style.color = 'white';
currentBtn = this;
if (audio) {
audio.pause();
audio = null;
}
audio = new Audio();
audio.addEventListener('canplay', play);
audio.src = musicList[index];
}
} )
//点击停止
stopBtn.onclick = function (){
audio.pause()
}
//开始按钮
function play(){
audio.play()
audioContext = new AudioContext()
sourceNode = audioContext.createMediaElementSource(audio)
analyser = audioContext.createAnalyser()
sourceNode.connect(analyser)
analyser.connect(audioContext.destination)
parse()
}
//暂停按钮
function parse(){
let freqUnit = []
let freqArray = new Uint8Array(analyser.frequencyBinCount)
analyser.getByteFrequencyData(freqArray)
//设置步长
let step = Math.round(freqArray.length / 7)
for (let i = 0; i < 7; i++) {
freqUnit.push(freqArray[i * step] / bassRatioPosition)
}
animatePhone(freqUnit)
console.log(freqUnit);
if(!audio.paused){
requestAnimationFrame(parse)
}
}
需要源代码的也可以前往Gitee地址,git clone或下载,浏览器直接运行music.html即可。