Reputation: 55
What I want to do is an 'addEventListener' function. When the canvas is clicked and the raindrop appears, a sloshing sound is made. So no matter how many times you click, the sound will always play.
I had no idea what it was called and my professor suggested it. However, when I combed the google, all I find is button clicks or Jquery things. I don't want a button and I am not allowed to use Jquery.
As always, I only seek a push in the right direction.
Thanks for all the help you all have given me thus far.
var canvas;
var context;
var drops = [];
var squares = [];
function Drop(x,y,color){
this.x = x;
this.y = y;
this.color = color;
this.dy = Math.random();
}
function Square(x,y,w,color){
this.sx = x;
this.sy = y;
this.sw = w;
this.color = color;
this.qy = Math.random();
}
function init(){
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
alert("Hello!\nClick on the screen for rain drops!");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas();
canvas.onclick = function(event){
handleClick(event.clientX, event.clientY);
};
setInterval(handleClick,5);
}
function handleClick(x,y,w){
var found = false;
for(var i = 0; i<drops.length; i++){
d = Math.sqrt((drops[i].x-x)*(drops[i].x-x) + (drops[i].y-y)*(drops[i].y-y));
if(d<=5){
drops.splice(i,1);
found = true;
}
}
fillBackgroundColor();
if(!found){
var colors = ["#000080", "#add8e6", "blue"];
var color = colors[Math.floor(Math.random()*colors.length)];
drops.push(new Drop(x,y,color));
squares.push(new Square(x,y,w,color));
}
for(var i = 0; i<drops.length; i++){
drawDrop(drops[i]);
}
for(var i = 0; i<squares.length; i++){
drawSquare(squares[i]);
}
}
function drawDrop(drop){
context.beginPath();
context.arc(drop.x, drop.y, 5, 0, Math.PI);
context.fillStyle = drop.color;
context.moveTo(drop.x - 5, drop.y);
context.lineTo(drop.x, drop.y - 7);
context.lineTo(drop.x + 5, drop.y);
context.closePath();
context.fill();
if (drop.y + drop.dy > canvas.height || drop.y + drop.dy < 0)
drop.dy != -drop.dy;
drop.y += drop.dy;
};
function drawSquare(square){
var sw = Math.floor(4);
var sx = Math.floor(Math.random() * canvas.width);
var sy = Math.floor(Math.random() * canvas.height);
context.beginPath();
context.rect(sx, sy, sw, sw);
context.fillStyle = '#add8e6';
context.fill();
};
function fillBackgroundColor(){
context.fillStyle = 'gray';
context.fillRect(0,0,canvas.width,canvas.height);
}
function resizeCanvas(){
canvas.width = window.innerWidth - 20;
canvas.height = window.innerHeight - 20;
fillBackgroundColor();
for(var i = 0; i<drops.length; i++){
drawDrop(drops[i]);
}
for(var i = 0; i<squares.length; i++){
drawSquare(squares[i]);
}
}
function degreesToRadians(degrees) {
return (degrees * Math.PI)/180;
}
window.onload = init;
</script>
</head>
<body>
<canvas id='canvas' width=500 height=500></canvas>
</body>
Upvotes: 2
Views: 4807
Reputation: 54089
Clicking a Canvas or any element
To add an event listener to the canvas you just need the element, you can get it from the DOM in many ways, I have used getElementById
and its unique id. Then to add a click
event just attach a listener and the function to be called.
This will call playSound each time the canvas is clicked on.
var canvas = document.getElementById("canvasID"); // get the canvas
canvas.addEventListener("click",playSound); // call playSound when clicked
// See below for the function playSound
You could also add event listeners for mousedown and mouseup as click is only called when the mouse button is released, which may not be the desired effect.
Loading a sound
As the sound needs to be loaded and that may take some time you need to have a way of indicating that the sound has loaded and is ready to play. For this simple answer a semaphore will do the trick. Just set a property to indicate loaded.
var sound = new Audio(); // create the audio
sound.src = "SoundFileURL.mp3"; // set the resource location
sound.oncanplaythrough = function(){ // When the sound has completely loaded
sound.readyToRock = true; // flag sound is ready to play
// I just made it up and can be anything
};
sound.onerror = function(){ // not required but if there are problems this will help debug the problem
console.log("Sound file SoundFileURL.mp3 failed to load.")
};
Repeated sound play
The playSound
function. An Audio resource can only be played as one sound. You can not play it over the top of itself. When repeatedly clicking you need to reset the sound playback position so it starts again. To do this just set the currentTime
to 0 (the start of the sound) and call the method play
. This way each click will start the sound or rewind and start again, no need to check if its playing. If you want the sound to overlap you need to load in several copies of it and cycle which one you play with each click.
// assuming sound is in scope from above code
function playSound(){
if(sound && sound.readyToRock){ // check for the sound and if it has loaded
sound.currentTime = 0; // seek to the start
sound.play(); // play it till it ends
}
}
Overlapping the sound
Playing the same sound from an array so it overlaps. Load the same sound several times into an array. Keep a variable that will point to the next sound in the array to play when the user calls the function (via click event) then seek to the start and play the sound. Increment the next sound pointer ready for the next click.
This will have the sound play over itself. The number of times to load the sound will depend on how often the user clicks and how long the sound is. Don't go overboard as there is a point where you can't tell if a new sound has started or if a playing one has been restarted.
Load same sound several times
var sounds = []; // array to hold the sound
for(var i = 0; i < 4; i++){
var sound = new Audio(); // create the audio
sound.src = "SoundFileURL.mp3"; // set the resource location
sounds.push(sound); // put the sound on the array
}
Playing the array of sounds
// assuming that the array sounds has the sounds you want to overlap
// and that they have been loaded so there is no need to check their status
var soundToPlay = 0; // the next sound to play
// the click event function.
function playSound(){
var sound = sounds[soundToPlay % sounds.length]; // get the next sound
// making sure that it
// does not go past the
// of the array
sound.currentTime = 0; // seek to start
sound.play(); // play it
soundToPlay += 1; // point to the next sound to play
}
Upvotes: 5