我正在尝试根据Do Re Mi等键制作一个简单的钢琴。我的想法是,每个声音(Do Re Mi ..)将对应于按键事件播放。我按照按键选择的顺序收集数组中的每个有效音频元素。之后,一旦用户按下“播放”按钮,所有声音将作为曲调一起播放。
到目前为止,情况正常。但是,在曲调播放期间,所有声音都在一起播放。似乎,它们彼此重叠。我希望在每个声音之后添加暂停,就像它们最初播放的方式一样。
Ex:做(2s暂停),Re(没有暂停)Re,(1s暂停)Mi,Do(3s暂停),....
我尝试使用睡眠功能添加暂停,但它无效。在我的控制台输出中,正确打印数组元素(收集音频元素和相应的暂停),并且也正确地暂停,但是在音频播放期间不保持暂停。很感谢任何形式的帮助。这是我的代码,
HTML
<!DOCTYPE html>
<head>
<title>do-re-mi keyboard</title>
<link type="text/css" href="style.css" rel="stylesheet"/>
</head>
<body>
<div id="main-div">
<h1>Let's create some awesome music ....</h1>
<div class="keys">
<div data-key="68" class="musicKey"><p>D</p><span>(Do)</span></div>
<div data-key="82" class="musicKey"><p>R</p><span>(Re)</span></div>
<div data-key="77" class="musicKey"><p>M</p><span>(Mi)</span></div>
<div data-key="70" class="musicKey"><p>F</p><span>(Fa)</span></div>
<div data-key="83" class="musicKey"><p>S</p><span>(So)</span></div>
<div data-key="76" class="musicKey"><p>L</p><span>(La)</span></div>
<div data-key="84" class="musicKey"><p>T</p><span>(Ti)</span></div>
<button id="playTune">Play</button>
<button id="refresh">Refresh</button>
</div>
</div> <!--main div ends -->
<audio data-key="68" src="audio/do.mp3" type="audio/mpeg"></audio>
<audio data-key="82" src="audio/re.mp3" type="audio/mpeg"></audio>
<audio data-key="77" src="audio/mi.mp3" type="audio/mpeg"></audio>
<audio data-key="70" src="audio/fa.mp3" type="audio/mpeg"></audio>
<audio data-key="83" src="audio/so.mp3" type="audio/mpeg"></audio>
<audio data-key="76" src="audio/la.mp3" type="audio/mpeg"></audio>
<audio data-key="84" src="audio/ti.mp3" type="audio/mpeg"></audio>
<script src="soundBox.js" type="text/javascript"></script>
</body>
</html>
CSS
body{
margin:0;
}
#main-div{
height:100vh;
width:100%;
background-color: #ffffcc;
background:url('image/sand.jpg');
}
h1{
text-align: center;
margin-top:0;
padding-top: 50px;
font-family: 'Rouge Script', cursive;
font-size: 40px; font-weight:bolder;
line-height: 48px; margin: 0 0 20px;
color: #e65c00;
text-shadow: 1px 1px 2px #803300;
}
.keys{
height: 200px;
width:700px;
position:absolute;
top:50%;
left:50%;
background-color:yellow;
transform:translate(-50%,-50%);
align-items: center;
}
.musicKey{
height : 80px;
width:80px;
border-radius: 10px;
background-color:red;
margin-top:60px;
margin-left:10px;
margin-right:10px;
float:left;
align-items:center;
/* box-shadow: inset -3px -5px 2px 1px #515151;*/
text-align:center;
transition:all 0.07s;
}
.musicKey span{
text-align:center;
font-size: medium;
padding-top:30px;
}
.musicKeyPressed{
transform:scale(1.1);
border-color:black;
box-shadow: 3px 1px 1px 1px #515151;
}
#playTune{
float:right;
height:40px;
width:80px;
background-color:gray;
margin:10px;
}
#refresh{
float:right;
height:40px;
width:80px;
background-color:green;
margin:10px;
}
的JavaScript
document.addEventListener("keydown",playMusic);
let keyArr = document.querySelectorAll(".musicKey");
var audioKeyProp = {};
var tune = [];
var keyCount =0;
var start =0;
var oldStart =0;
function sleepFunc(time) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > time){
break;
}
}
}
document.getElementById("refresh").addEventListener("click",function(){
tune = [];
start =0;
oldStart =0;
keyCount =0;
});
document.getElementById("playTune").addEventListener("click",function(){
//console.log("tune array = " + tune);
if(tune.length > 0)
{
tune.forEach(function(item){
// console.log("tune item = "+ item);
if(typeof(item) === "number")
{
sleepFunc(item);
}
else
{
item.play();
item.currentTime=0;
}
});
}
});
keyArr.forEach(function(item){
let tempVal = item.getAttribute('data-key');
audioKeyProp[tempVal] = document.querySelector(`audio[data-key="${tempVal}"]`);
});
function backToOriginalPosition(e)
{
if(e.propertyName !== "transform") return;
this.classList.remove("musicKeyPressed");
}
function playMusic(event)
{
var pressedKey = event.keyCode;
var timeElapse = 0;
start = new Date().getTime();
if(keyCount >= 1)
{
timeElapse = start - oldStart;
}
var keyDiv = document.querySelector(`div[data-key="${pressedKey}"]`);
var audioElement = audioKeyProp[pressedKey];
if(audioElement && keyDiv)
{
console.log("duration= " + audioElement.duration);
oldStart = start;
keyCount++;
tune.push(timeElapse);
tune.push(audioElement);
audioElement.currentTime =0;
audioElement.play();
keyDiv.classList.add("musicKeyPressed");
keyDiv.addEventListener("transitionend",backToOriginalPosition);
}
}
答案 0 :(得分:0)
尝试在setInterval
之外声明一个等于0的变量,假设为var noteIndex = 0
。在setInterval
内播放第一个音符:tune[noteIndex]
,然后递增noteIndex
。
所以你的代码应该是这样的:
var tune = []; //Set tunes to play
var pause = []; //Set tunes breaks
var noteIndex = 0;
var playNotes = setInterval(function(){
tune[noteIndex].play();
noteIndex++;
if (noteIndex > tune.length) { //Stop the interval if all notes are played.
noteIndex = 0; //Reset 'noteIndex' for next use.
break;
}
}, pause[noteIndex]);
希望这有帮助。