HTML5 Canvas [126]
var slideIncrement = playBackW/audioElement.duration;
Now we need to calculate the x position of the slider. The x position is the sum of the slider’s starting position (the place on the canvas where the controls start plus the width of the play/pause button: controlStartX+bW) plus the audio’s current play position. We calculate the play position by taking the ratio we just created, sliderIncrement, and multiplying it by the current play time of the audio clip (audioElement.currentTime). That’s it!
var sliderX = (playBackW,bH,controlStartX+bW) +
(slideIncrement*audioElement.currentTime);
Now all we need to do is draw the image onto the canvas, and then test to see whether the audio clip has ended. If it has ended, we put the play position back to the beginning of the playback area and call audioElement.pause() to pause the audio clip. That is, unless the loop property is sent, in which case we start playing the audio clip from the beginning by setting the currentTime property to 0:
context.drawImage(buttonSheet, 238,0,sliderW,bH,sliderX,controlStartY,sliderW,bH);
if (audioElement.ended && !audioElement.loop) {
audioElement.currentTime = 0;
audioElement.pause();
}
This leads us right into our next topic, handling the play/pause button.
Play/Pause Push Button: Hit Test Point Revisited
The first thing we need to do when implementing the play/pause button is create the event handler for the mousemove event. The function really is just the standard cross-browser code we introduced earlier in the book for tracking the mouse position, depending on which properties the DOM in browsers supports: layerX/layerY or offsetX/offsetY. This function is called every time the mouse is moved on the canvas to update the mouseX and mouseY variables. Those variables are scoped to canvasApp() so all functions defined inside of it can access them:
function eventMouseMove(event) {
if ( event.layerX || event.layerX == 0) { // Firefox
mouseX = event.layerX ;
mouseY = event.layerY;
} else if (event.offsetX || event.offsetX == 0) { // Opera
mouseX = event.offsetX;
mouseY = event.offsetY;
}
}
Now we need to create the eventMouseUp() handler function. This function is called when the user releases the mouse button after clicking. Why after and not when the mouse is clicked? Well, one reason is because we generally use the mousedown event for the start of a “dragging” operation, which we will show you shortly.
The heart of this function is a hit test point-style collision detection check for the buttons. We discussed this in depth in Chapter 6 when we created the buttons for the video puzzle game (CH6EX10.html). Notice that here we are using the variables we create to represent the x and y locations of the button (playX, playY) and the width and height of a button (bW, bH) to form the bounds of the area we will test. If the mouse pointer is within those bounds, we know the button has been clicked:
function eventMouseUp(event) {
if ( (mouseY >= playY) && (mouseY <= playY+bH) && (mouseX >= playX) &&
(mouseX <= playX+bW) ) {
NOTE
If you had images stacked on top of one another, you would need to store some kind of stacking value or z-index to know which item was on top and was clicked at any one time. Because the canvas works in immediate mode, you would have to “roll your own” just like the other functionality we have discussed.
After a hit is detected, we need to determine whether we are going to call the play() or pause() method of the HTMLAudioElement object represented by the audioElement variable. To figure out which method to call, we simply test to see whether the audio is paused by checking the audioElement.paused property. If so, we call the play() method; if not, we call pause(). Recall that the HTMLAudioElement.paused property is set to true