我使用JS和HTML5编写了一个简单的音乐键盘,现在我想在播放新音符时强制暂停前一个音符。
var keyProto = {
// other attributes and methods
play: function() {
var sound = new Audio("wav/" + timbre + this.name + this.octave + ".wav");
if(!prevSound.paused && !prevSound.ended) {
prevSound.pause();
}
sound.play();
prevSound = sound;
}
};
然而,之前的声音仍然存在。
编辑:这是整个程序的“子集”,它具有相同的问题。
var soundFileNames = ["wav/sineA3.wav", "wav/sineB3.wav"];
var prevSound = new Audio(soundFileNames[0]);
var keys = [];
var keyProto = {
soundFileName: "-",
x: 0,
y: 0,
w: 0,
h: 0,
setDimensions: function(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
},
draw: function(ctx) {
ctx.strokeStyle = "#000000";
ctx.strokeRect(this.x, this.y, this.w, this.h);
},
within: function(mx, my) {
return this.x < mx && this.x+this.w > mx && this.y < my && this.y+this.h > my;
},
play: function() {
var sound = new Audio(this.soundFileName);
prevSound.pause();
sound.play();
prevSound = sound;
}
};
// Redraw canvas if window is resized
var resize = function() {
var cnvs = document.getElementById("cnvs");
cnvs.height = window.innerHeight;
cnvs.width = window.innerWidth;
var c2 = cnvs.getContext('2d');
c2.clearRect(0, 0, cnvs.width, cnvs.height);
var midY = cnvs.height / 2;
var margin = cnvs.width / 4;
var keyWidth = (cnvs.width - 2*margin) / keys.length;
var keyHeight = midY / 2;
for(var i = 0; i < keys.length; i++) {
keys[i].setDimensions(margin + i*keyWidth, midY-keyHeight/2, keyWidth, keyHeight);
keys[i].draw(c2);
}
}
// mouse pressed
var handleMouseDown = function(event) {
var cnvsRect = document.getElementById("cnvs").getBoundingClientRect();
mouseX = event.clientX - cnvsRect.left;
mouseY = event.clientY - cnvsRect.top;
for(var i = 0; i < keys.length; i++)
if(keys[i].within(mouseX, mouseY))
keys[i].play();
}
// "main"
for(var i = 0; i < soundFileNames.length; i++) {
var newKey = Object.create(keyProto);
newKey.soundFileName = soundFileNames[i];
keys.push(newKey);
}
resize();
好的衡量标准,HTML
<html>
<head>
<title>Fun Key</title>
</head>
<body onmousedown="handleMouseDown(event)"
onresize="resize()"
style="margin : 0px">
<canvas id="cnvs"</canvas>
<script src="funKeyMin.js"></script>
</body>
</html>
prevSound
是一个全局变量,声明为var prevSound = new Audio("wav/sineA3.wav");
。使用console.log()
进行一些检查告诉我:
prevSound
看起来像我期望的那样:像<audio preload="auto" src="wav/sineD3.wav">
这样的对象,其中文件名始终与最后播放的声音匹配。prevSound
已经认为在遇到prevSound.paused
时已暂停(true
为if
),无论之前的音符是否仍在播放。删除if
子句并离开prevSound.pause()
不会改变行为。我可以在prevSound.pause()
例程(作业draw()
之后)结束时调用prevSound = sound
,新声音会立即暂停。
使用keyProto
从Object.create(keyProto)
创建使用此方法的关键对象。我最近读到原型继承比使用构造函数更受欢迎,这是我第一次使用它。但是,我的猜测是问题源于全局变量的一些细微差别。