HTML5 : Canvas with mouse interaction.

Here we are going to study about the creation of Canvas dynamically and the basic mouse interactivity with the Canvas elements.

The source files for this example is here for you to download and play.

We are going to use a separate sprite sheet and try to make the scene a little more interesting than the last one. I would say to download the source files and see the example for yourself to see what is it doing. Basically there is a scene on the background with 6 tables and a girl doing some experiment on third table. Towards the left top corner of the scene, there is another girl trying to do some magic with its magic wand. If you look at the code, the scene with the girl doing experiment is a straight forward drawing from the sprite sheet as we did that in last tutorial. The girl with the magic wand is drawn in a dynamically created Canvas. The code looks as below.

//creating canvas dynamically
canvasGirl=document.createElement('canvas'); 
canvasGirl.width=100; 
canvasGirl.height=100;
//get the context
contextGirl=canvasGirl.getContext('2d');
//customise canvas
canvasGirl.style.background='transparent';
canvasGirl.style.zIndex=5;
//add the canvas to the document
document.body.appendChild(canvasGirl);

The first thing is to create a new canvas with “createElement(‘canvas’)”. That will make a new canvas. Now we have to get the context to draw something on it. This is done with “getContext(’2d’)” as usual, nothing new here. And lastly, we have to add our newly created Canvas to the document and this is done with “document.body.appendChild(canvasGirl);” code. Thats beautiful. Everything else in the code is just configuring the canvas.
Once the canvas and context are available to us, we can do anything we are able to do to a Canvas. So the girl with the magic wand is drawn to the context of this Canvas element. The code looks as below.

resetContext(canvasGirl,contextGirl);
contextGirl.drawImage(photo, 108*counter+10, 900, 96, 64, 0, 0, 96, 64);

First we are resetting the Canvas, so as to draw new content on each timer. Since the girl with magic wand is actually an animation, we call the code above repeatedly on a timer event. And first we clear the context with our own function and then redraw an image from sprite sheet at the same place on the canvas, so as to make an animation. If you are following along with the previous tutorials then the reseting of context code should not be new to you, else the code looks as as below.

resetContext=function(canvasRef,contextRef){
	contextRef.clearRect(0,0,canvasRef.width,canvasRef.height);
};

All we have, are two layers of drawing and animation drawn from the same sprite sheet.
Lets do some mouse interactivity with these elements. The code looks as below.

//------------ adding mouse interaction --------------
$('#board_one').mouseup(function() {
  	alert('Canvas with Tables');
});
$(canvasGirl).mouseup(function() {
  	alert('Canvas with Girl, doing magic.');
});

The trick here is JQuery’s neat job. Just remember anything wrapped with $() will give a JQuery element of the same HTML element. So our dynamically created Canvas is made an JQuery element by

$(canvasGirl)

Notice that there is no ‘#’ before the name as it is before ‘board_one’, thats for the ‘board_one’ we are referring the HTML element with id ‘board_one’, while the other one we are creating dynamically in javascript and converting it to a JQuery equivalent.
Thats nice and if you have not done yet, please go ahead and click on the board to get an alert showing different message and if you click on the girl with magic wand, that will alert a different message.
This is quite simple and straight forward interactivity, but I think you got the point.
Happy coding :)

And yes, I made it to one month of continuous posting, highly influenced by Keith Peters. Though it was not all javascript and I missed some dates, but all in all, the number of posts in a month is achieved. I am quite happy about my effort and a big thanks to all of you, who read it.

HTML5 : animating on a Canvas with sprite sheet

We have already seen how to animate on Canvas in one of our last tutorials. That was quite straight forward as we were using Canvas drawing straight out of the box. Here we will use our newly learnt tools(loading and drawing bitmap image in canvas) to make an animation.
The source files are here for you to download and play.
The concept is the same though as in re-drawing in the canvas at a regular interval, but instead of drawing with drawing API, we will be drawing image.
First of all lets understand what a sprite sheet is? The sprite sheet is an image! Just an image? Yes, its just an image file. In that image file, we should have almost all the images needed for our purpose. That means, one image file consisting of all the images required in a project. Why its necessary? Good question. The reason being we have just one call to the server and all our image data is loaded. The next reason is to update the image data. Suppose we want to update the graphics all at once, we just have to update one image file.
If you are going through the image file in our source, the image file has 12 different images of a character. All we are going to do is, cycle over each character over a time. That we can do with a “setInterval()” javascript function.
Lets see the javascript code first and then we will go learn it.

$.ready()
{
	//------------- 1. defining the variables and functions----------------
	var resetCanvas,resetContext,
		canvas_1,context_1,
		image_data,photo,loadPhoto,imageLoaded,timer,onTimer,counter,animate;
	//------------- 2. configuring ---------------------------------------
	//get the canvas and context
	canvas_1=$('#board_one').get(0);
	context_1=canvas_1.getContext('2d');
	counter=1;
	//---------------functions----------------------------------
	//resetting the width and height, it automatically resets the canvas
	//clear the board, quick and dirty, its a HACK!!
	resetCanvas = function (canvasRef){
		canvasRef.width=canvasRef.width;
		canvasRef.height=canvasRef.height;
	};
	//clear the board
	resetContext=function(canvasRef,contextRef){
		contextRef.clearRect(0,0,canvasRef.width,canvasRef.height);
	};
	
	imageLoaded=function(evt)
	{
		var originalPic=evt.target; 
		animate();
	};
	
	loadPhoto=function(path)
	{
		photo.src=path;
	};
	
	animate=function(){
		timer=setInterval(onTimer,150);
	};
	
	onTimer=function(){
		resetContext(canvas_1,context_1);
		
		//draw again
		if(counter>=12)
		{
			counter=0;
		}
		context_1.drawImage(photo, 97*counter, 0, 97, 95, 230, 110, 97, 95);
		counter++;
		//clearInterval(timer);//incase we need to stop the animation
	};
	
	//----------------3. using-----------------------------
	image_data=context_1.createImageData(canvas_1.width,canvas_1.height);
	photo=new Image();
	photo.onload=imageLoaded;
	loadPhoto('images/walkSheet.png');
};

In the beginning we have just defined the variables, then populating them with the required values and scripts. Lastly we are calling our methods and using these variables.
In the beginning we get our canvas and its context. Intitialised the “counter” to 1 as we have 12 different positions of the image, we will be needing a counter to move to next position. So once these properties are populated, we have created some functions, which we use. Then moving on to the actions, firstly there is an “image_data” object, I have created, but not used. That is just to show we can create an image data object from the canvas, which is used to pixel manipulation. So the first thingon making our animation is making an Image object with

photo=new Image();

Then we have to provide an event handler for its image load event, that is done with the code below.

photo.onload=imageLoaded;

If you remember we have already created the “imageLoaded” function, which looks as below.

imageLoaded=function(evt)
	{
		var originalPic=evt.target; //just for the shake of understanding
		animate();
	};

Here the first the “originalPic” variable is defined just to know that we can get the image from the event object as “event.target” . So all in all this “imageLoaded” function actually initialises our animation by calling “animate()”.

animate=function(){
		timer=setInterval(onTimer,150);
	};

And “animate()” function actually intialises the timer for animation and calls “onTimer” function repeatedly at each 150 milliseconds.

onTimer=function(){
		resetContext(canvas_1,context_1);
		//draw again
		if(counter>=12)
		{
			counter=0;
		}
		context_1.drawImage(photo, 97*counter, 0, 97, 95, 230, 110, 97, 95);
		counter++;
		//clearInterval(timer);
	};

This is the place, where all the action is happening. First we have to clear our canvas, that is being done on the first line of this function. Next we check, whether the “counter” is more than 12, if it is then reset it to 0. Thats for we have just 12 different images. Now the line which actually draws our animation is

context_1.drawImage(photo, 97*counter, 0, 97, 95, 230, 110, 97, 95);

This is actually drawing part of the sprite sheet to a particular are in the canvas. Its like copying a portion from the sprite sheet and pasting it in the Canvas. On the next timer event (ie; after another 150 milliseconds, it will copy another portion and paste it in the same location.) we take another portion from the sprite sheet and paste it in the same area of canvas. Since we are clearing the canvas and re-drawing it over a period of time, it seems as if the character is animating! The time of 150 milliseconds is just a guess, we can lower it to see the jerky animation or higher it to see the character move faster. The other values as 97,95 are the width and height of each image in pixels, so that would be different for different sprite sheets.
The last line increments the counter by one.
Now we have a nice looking animation in our HTML Canvas.

Things to not here is, I struggled for sometime to see this working, for I was providing wrong parameter values (97,95 seemed perfect). So if your animation is not visible, first see if the parameter values are correct. Even one pixel higher than the actual image height or width will make the whole thing invisible. Though lower values work fine.

Happy coding.

HTML5 : Canvas pixels, part II

Now we know we can create and manipulate pixels in the Html5 Canvas. That opens doors to some of cool effects we can make with this tool. Here we will make an image invert its color.
The thing to remember here is, we have to get the image data from the context after our image is drawn. That means instead of

createImageData(width,height)

we have to use

getImageData(intialX,initialY,width,height)

The function for creating this look as below,

filterImage=function()
	{
		// Get the CanvasPixelArray from the given coordinates and dimensions.
		var imgd = context_one.getImageData(0, 0, width, height);
		var pix = imgd.data;
		// Loop over each pixel and invert the color.
		for (var i = 0, n = pix.length; i < n; i += 4) {
		  pix[i  ] = 255 - pix[i  ]; // red
		  pix[i+1] = 255 - pix[i+1]; // green
		  pix[i+2] = 255 - pix[i+2]; // blue
		  // i+3 is alpha (the fourth element)
		}
		// Draw the ImageData at the given (x,y) coordinates.
		context_one.putImageData(imgd, 0, 0);
	}

first of all, we take the image data object from the context. Then like the previous example, we loop over each pixel and subtract the channel values from the maximum value so as to invert the color of each pixel. And finally we have to put them into context for rendering.
I would suggest the same thing here as, please try this in every possible browser. While the same code does not work for me on Chrome, it did work in latest Opera.
The source code is here for you to download and play.
Hope that helps someone.

HTML5 : Canvas pixels

Once we know we can do an image drawing in a canvas, lets see if we can at all make a new image from a blank canvas. The answer is yes. We have absolutely accessible to each pixel values of the context of the Canvas.

Let me say you here, if you are not getting the result in one browser, try other browsers. I had tried a long time with the same code in Chrome without any result! But it worked out in latest version of Opera !! Not sure whats wrong but if you test it in other browsers it will save you a lot of time.

The code for image creation is as below.

createImage=function()
	{
		// Create an ImageData object.
		var imgd = context_one.createImageData(width,height);
		var pix = imgd.data;
		// Loop over each pixel and set a transparent red.
		for (var i = 0; n = pix.length, i < n; i += 4) {
		  pix[i  ] = 255; // red channel
		  pix[i +1] = 0; // green channel
		  pix[i +2] = 0; // blue channel
		  pix[i+3] = 255; // alpha channel
		}
		// Draw the ImageData object at the given (x,y) coordinates.
		context_one.putImageData(imgd, 0,0);
	}

All we have to do is create an image data with a width and height, that is done as

var imgd = context_one.createImageData(width,height);

The above code, I have taken the width as canvas width and height as canvas height.
Now we will access each element of that image data array. Since its just an array the pixel values of each pixel is stored linearly as "red,green,blue,alpha" and so we have to loop over each 4th element and get the values of all the channels of each pixel. Thats exactly what our for loop is doing. Then we are only populating the red channel to its max, since we want a red fill canvas image :) !
Lastly the image data must be put on the context so as to render the pixels. The following code does that.

context_one.putImageData(imgd, 0,0);

Thats a simple pixel manipulation we did now with our canvas element.
The source code is available here for you to download and play.

HTML5 : Image on Canvas

Here we will learn about adding image in a canvas.
The concept is to create an Image object, add listener for load event, load the image, on the load complete handler get the image data and draw it on the context of the canvas.

p=new Image();
p.onload=imageLoaded;
imageLoaded=function(evt)
{
var image=evt.target;
context.drawImage(image,100,100);
}
p.src="img/myImage.jpg";

That’s all for an image to be drawn on the Canvas.

Posted from WordPress for Android through my “HTC Wildfire”.

The publish date is taken a day back as to make a post each day.

HTML5 : Some more libraries

While going good with at least one post each day, I am not sure what to put next for HTML5 Canvas.
I came across some more libraries for HTML5 Canvas.

KineticJS
Doodle.js
Image Manipulation on Canvas
pixastic
CamanJS
tiffus
JSDrawing
PaintbrushJS
Javascript Code Quality tool
JSLint
Javascript programming
Backbone
Underscore
Knockout
Sugar

phpjs
pdf.js
iScroll
zepto.js

node.js
CoffeeScript

We are going good with HTML5 Canvas, I hope there is nothing much left for the basic concepts except one or two, which we will be covering soon. Leave a comment if you feel any tutorial in particular to be included.
Stay tuned and thanks for being here.

HTML5 : multiple Canvas

The interesting thing about Canvas is we can have more than one Canvas and even we can create Canvas dynamically through javascript. Why would we need more than one Canvas !?! There may be many answers to this, but the most important of all is, I think, when we need to update the Canvas. If you remember we have made an animation in our previous tutorial. And diving a little inside of that code will show you that we are redrawing it on each timer event.
The whole idea of animating in Canvas revolves around updating the Canvas on each timer event. But we also know that once something is written/drawn in Canvas
we can not have a reference to it. So in the other hand we have to re-write or re-draw everything again. And this redrawing over and again will take us to a performance problem. Re-drawing the whole canvas with all the elements, again and again is not a good idea and we must avoid it if we can. The best thing to do is to separate elements to different Canvases. And we will never update the Canvas which contains the elements we do not need to be changed. Then only refresh the Canvases whose content needs updating upon timer event. Seems like a plan ? I have done this with the example source code, for your reference.
The source code of the example, contains two canvases and I am updating only the second Canvas as it needs updating.

Point to note here is Canvas refresh does not mean only updating the values, but actually it means erase everything from the Canvas and re-draw everything with the updated value.

Hope that helps to understand the power of Canvas a little better.