Showing posts with label HTML. Show all posts
Showing posts with label HTML. Show all posts

Friday, July 22, 2011

Posted by SAMAJ SHEKHAR

0

Introduction to HTML5 <Canvas>: Part 2 (Example)


This post is the sequel to my previous post of Introduction to HTML5 <Canvas>: Part 1 and shows a walkthrough example of using canvas for some static 2D drawing (for Introduction to animation wait for my next post). This is the second post to my “HTML5 <Canvas>” series.
In previous post we saw how <Canvas>'s context gives us an API with set of methods and properties to draw on its surface, now in this post we will use some of those methods to draw a logo of one of my favorite game PORTAL2.
Sorry, but your Browser Dosen't Support HTML5 <canvas>
Above is the actual completed art drawn on canvas, and below we will see how we draw that art piece by piece. And Let me tell you this article is just for introducing you to the use of various methods provided by canvas and may not show the best and efficient way of drawing on it. So keeping that in mind, let’s get started.

First things first

As you may know by now that before any drawing we need to have a handle on <Canvas> element to do manipulations, and that handle is the context object of the <Canvas>. The context of the <Canvas> element provides us all that API of methods to do drawing and manipulation on <Canvas>. To get the context we use "getContext()” method and pass in the string “2d” as parameter * . Also since we feel more natural using “degrees” for specifying angles but all functions of canvas context take clockwise “radians” as parameter, we’ll use following function to convert degree into anticlockwise* radians. Also note that it is recommended to use "save()” and “restore()” methods of context to save the current state of the context on the stack before any manipulation & transformation and restore it back to its previous state respectively.
*(for details check my previous post or w3c draft)
//context of the canvas
var ctx = document.getElementById("portalcanvas").getContext("2d"); 
//function to convert radians to degrees
var acDegToRad = function(deg){
		return deg* (-(Math.PI / 180.0));    
}

Drawing the “2”

We’ll start by drawing the number “2” on the <Canvas>. It consists of 3 pieces the base rectangle, a slant rectangle and an arc.
  • 2’s Base: The base rectangle is the easiest of all to draw, just set the “ fillStyle” property of the context to light gray color and use “fillRect( x, y, width, height)” method to draw the rectangle.
    ctx.save();
    ctx.fillStyle = "rgb(110,110,110)";
    ctx.fillRect(20,200,120,35);
    ctx.restore();
    
    If we want we could also draw above rectangle as a small horizontal line with line-width equal to the height of the above rectangle. But that would involve more steps like creating a path and then drawing the line along the path, which is more complicated for this primitive shape.
  • 2’s Slant: The slant rectangle is just a simple rectangle but elevated to an angle of 35 Degrees. So to create a slant rectangle first we will translate the origin of the coordinate space (i.e., the transformation matrix) to the top edge of 2’s base rectangle using “translate( newX, newY)” and then rotate the coordinate space by 35 degrees in anti-clockwise direction, taking new origin as the pivot/center, by using the “rotate(radians)” method and then simply draw the rectangle using fillRect( x, y, width, height).
    ctx.save();
    ctx.fillStyle = "rgb(110,110,110)";
    ctx.translate(20,200);
    ctx.rotate(acDegToRad(35));
    ctx.fillRect(0,0,100,35);
    ctx.restore();
    
    Also note that how we have used save() before any manipulation and then used restore() after drawing, this makes sure that the translation and rotation of coordinate space does not affect rest of drawings we are about do later on. This way context state of the canvas always remains in previous state, in this case, the Initial state. Remember save() and restore() doesn’t save/restore the contents on the canvas, it just save/restore the state of properties/attributes like “fillStyle”, “strokeStyle”, “lineWidth”, etc and coordinate space on the <Canvas>drawing context.
  • 2’s Arc: The top arc of number “2” cannot be drawn by rectangle methods but can be simply drawn like a line arc whose line-width is equal to the height of previous rectangles. For creating any line shape we first start a path by calling “beginPath()” method, then call any shape method like “rect()”, “arc()”, “lineTo()”, etc to add them to path and then optionally call “closePath()” method to complete the path and start new one. For this step we will start a new path and add an arc to the path by using “arc(x,y,radius, startAngle, endAngle)” method. So far we have only created the path, to actually draw the arc on canvas we will call “stroke()” method. But since stroke will draw with default color, so before calling “stroke()“ we will set “strokeStyle” property of context to light gray.
    ctx.save();
    ctx.lineWidth = 35;
    ctx.beginPath();
    ctx.arc(77,135,40,acDegToRad(-40),acDegToRad(180),true); 
    ctx.strokeStyle = "rgb(110,110,110)";
    ctx.stroke();
    ctx.restore();
    

Drawing the “blue guy”

The next thing to be drawn is that blue guy coming out of the wall. This art consists of a wall, blue guy’s head, his tummy and then this hand & legs.
  • Wall: The wall is the just a simple slim and tall blue rectangle.
    ctx.save();	
    ctx.fillStyle = "rgb(0,160,212)";
    ctx.fillRect(162,20,8,300);		
    ctx.restore();
    
  • Head: The blue guy’s head is also a simple circle, but since we not have a direct method like “fillCircle()”, we’ll need to use a similar trick as we did for “2’s” arc. We will start a new path, add a full 360 degree arc and fill it with color. For filling we will use “fill()” method accompanied by “fillStyle” property set to light blue color, to fill the path with blue color thereby creating a filled circle.
    ctx.save();
    ctx.fillStyle = "rgba(256,256,256,0.75)";
    ctx.fillRect(0,0,300,350);
    ctx.fillStyle = "rgb(0,160,212)";
    ctx.beginPath();
    ctx.arc(225,80,35,acDegToRad(0),acDegToRad(360));
    ctx.fill();		
    ctx.restore();
    
    A thing to note here is that when you create a path you have two options, either to call “stroke()” method to draw that path using current “strokeStyle”, as we did earlier and will do for hand and legs, or to call “fill()”method to fill the path with current “fillStyle”, as we did just now for head and will do for tummy. We also have an option of calling “clip()” method (discussed later).
  • Tummy: The tummy of the blue guy is also drawn by creating a triangle path and filling the triangle with blue color. To create the triangle path we first start a new path, move the initial drawing point from origin or any last position (lets it be O) to a point on the wall below the head using “moveTo(x, y)” method which moves the drawing point from current draw point to a new point (let it be A) without adding the line between O & A to the path, then use “lineTo( x, y)” method which moves the drawing point to a new point (let it be B) and also adds the line between A & B to the path. Similarly add the third point (let it be C) to complete the three points of the triangle. This will also add the line between B & C to the path. Now optionally you can use “lineTo( x, y)” method to go back to point A and add line between C & A to the path and thus closing the path but by default the “fill()” will automatically assume a line between opening and closing points and will fill the enclosed area.
    ctx.save();
    ctx.fillStyle = "rgb(0,160,212)";
    ctx.beginPath();
    ctx.moveTo(170,90);  //point A
    ctx.lineTo(230,140); //point B
    ctx.lineTo(170,210); //point C
    ctx.fill(); //fill area between ABC
    ctx.restore();
    
  • Hand: For hand we will simply create two lines as we did above. A to B for shoulder to elbow and B to C for forearm. But by default the line is 1px wide first we will set “lineWidth” property of context to 25px, then since line’s ends and joints (at B) are rectangular by default, we will set both “lineCap” property, for line ends and “lineJoin” property to “round”. And since we want lines to be drawn instead of filling the space between, we will call “stroke()” method of context.
    ctx.save();	
    ctx.lineWidth = 25;
    ctx.lineCap = "round";
    ctx.lineJoin = "round"; 
    ctx.strokeStyle = "rgb(0,160,212)";
    ctx.beginPath();
    ctx.moveTo(222,150);  //point A
    ctx.lineTo(230,190);  //point B
    ctx.lineTo(270,220);  //point C
    ctx.stroke();
    ctx.restore();
    
  • Leg: The leg can be drawn exactly as we drew the hand so code will be much same as above except for the coordinates.
    ctx.save();
    ctx.lineWidth = 25;
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    ctx.strokeStyle = "rgb(0,160,212)";
    ctx.moveTo(160,210);  //point A
    ctx.lineTo(195,260);  //point B
    ctx.lineTo(160,290);  //point C
    ctx.stroke();		
    ctx.restore();
    
    But there is a problem with above code, the result leg doesn’t look like what we want. Part of the leg is hidden in the wall, so we need to clip the extra piece of leg from the drawing.
  • Clip Leg: With above code we didn’t got what we wanted but fret not, “clip()” method comes to rescue. Clip is similar to fill method but instead of filling the area enclosed by the path with some color, it creates an enclosed invisible boundary (outline of triangle is drawn in figure only to highlight the clip area) where any drawing on it clipped if it does not lie in the clipping region and only the drawing lying in the clipping region is shown. So to clip legs protruding through the wall, we’ll first create a clipping region by creating a triangular path with one of its side coinciding with the wall and then draw the leg same as we drew the hand.
    ctx.save();
    //code for drawing clipping region
    ctx.beginPath();
    ctx.moveTo(170,200);  //point A
    ctx.lineTo(250,260);  //point B
    ctx.lineTo(170,320);  //point C
    ctx.lineTo(170,200);  //back to point A to close the path
    ctx.clip();           //set the above path for clipping region
    //code for drawing leg
    ctx.lineWidth = 25;
    ctx.lineCap = "round";
    ctx.strokeStyle = "rgb(0,160,212)";
    ctx.lineJoin = "round";
    ctx.beginPath();
    ctx.moveTo(160,210);
    ctx.lineTo(195,260);
    ctx.lineTo(160,290);
    ctx.stroke();		
    ctx.restore();
    
And that’s all we need to do to create the that Portal 2 Logo, Below is an animated canvas showing all the pieces we used to draw it (in fact every image in this article is actually drawn on the <Canvas> elements) accompanied by complete combined code I used to draw it. So I hope that you liked this article and stay tuned for my next post where I will discuss 2D animation on <Canvas>.

(Actual Source Code)


(function(){
    var ctx = document.getElementById("portalcanvas").getContext("2d");
	//function to convert deg to radian
    var acDegToRad = function(deg){
			return deg* (-(Math.PI / 180.0));    
		}

	//save the initial state of the context
	ctx.save();		
	//set fill color to gray
	ctx.fillStyle = "rgb(110,110,110)";
	//save the current state with fillcolor
	ctx.save();

	//draw 2's base rectangle
	ctx.fillRect(20,200,120,35);
	//bring origin to 2's base
	ctx.translate(20,200);
	//rotate the canvas 35 deg anti-clockwise
	ctx.rotate(acDegToRad(35));
	//draw 2's slant rectangle
	ctx.fillRect(0,0,100,35);
	//restore the canvas to reset transforms
	ctx.restore();
	//set stroke color width and draw the 2's top semi circle
	ctx.strokeStyle = "rgb(110,110,110)";
	ctx.lineWidth = 35;
	ctx.beginPath();
	ctx.arc(77,135,40,acDegToRad(-40),acDegToRad(180),true);
	ctx.stroke();

	//reset canvas transforms
	ctx.restore();

	//change color to blue
	ctx.fillStyle = "rgb(0,160,212)";
	//save current state of canvas
	ctx.save();
	//draw long dividing rectangle 
	ctx.fillRect(162,20,8,300);
	//draw player head circle
	ctx.beginPath();
	ctx.arc(225,80,35,acDegToRad(0),acDegToRad(360));
	ctx.fill();

	//start new path for tummy :)
	ctx.beginPath();
	ctx.moveTo(170,90);
	ctx.lineTo(230,140);
	ctx.lineTo(170,210);
	ctx.fill();

	//start new path for hand
	//set lineCap and lineJoin to "round", blue color 
	//for stroke, and width of 25px
	ctx.lineWidth = 25;
	ctx.lineCap = "round";
	ctx.strokeStyle = "rgb(0,160,212)";
	ctx.lineJoin = "round";
	ctx.beginPath();
	ctx.moveTo(222,150);
	ctx.lineTo(230,190);
	ctx.lineTo(270,220);
	ctx.stroke();

	ctx.beginPath();
	ctx.moveTo(170, 200);
	ctx.lineTo(250, 260);
	ctx.lineTo(170,320);
	ctx.clip();	

	//begin new path for drawing leg
	ctx.beginPath();
	ctx.moveTo(160,210);
	ctx.lineTo(195,260);
	ctx.lineTo(160,290);
	ctx.stroke();
	
	//restore the context back to its initial state
	ctx.restore();
})()
READ MORE - Introduction to HTML5 <Canvas>: Part 2 (Example)

Tuesday, October 12, 2010

Posted by SAMAJ SHEKHAR

0

IE9 is here, So.. what's in for you as a Developer


After so many years of developers wishing for a better browser from Microsoft, one that was more consistent with web standards and would allow them to develop cross-browser websites leveraging the same markup, today marks the day that developers finally have that browser; Internet Explorer 9 Beta. It’s an important day because this release, although just a beta, is the culmination of a lot of effort and most importantly, listening, by the Internet Explorer team.
While the Internet Explorer browser has enjoyed widespread adoption by consumers, it hasn’t always been viewed fondly by the development community. The important work of building cross-browser compliant websites has often been cumbersome, due in part to differing interpretations of browser APIs in previous versions of Internet Explorer. The differences forced developers, myself included, to find workarounds for functionality that, in many cases, had a clearly defined standard behavior.

HTML5, CSS3, DOM

With Internet Explorer 9, there’s been a concerted effort by Microsoft to focus on standards-based functionality that will ease cross-browser development while providing the features needed to build rich and immersive websites. Take, for example, IE9’s support for many of the features of HTML5 and CSS3, the specifications which are defining the future of the web. By including support for features such as Canvas, video, @font-face, CSS3 media queries, SVG and many others, we now have a rich base to provide more compelling experiences to end users. In addition, by ensuring that these features are conformant to the defined specifications, the sites we build should work with any browser that also supports those specifications.
To take it a step further, the IE team has enhanced the performance of many of the new HTML5 features by taking advantage of the GPU. This means that text, graphics and video will be substantially smoother and more responsive allowing websites to perform more like true applications.
And at the DOM level, important changes have been made to be consistent with the defined specifications making it easier to whittle down browser-specific code. For example, support for the W3C DOM Events specification (addEventListener & removeEventListener) in place of the proprietary IE model (attacheEvent & detachEvent) has been one of the most welcomed changes to IE9 as has the introduction of getElementsByClassName, supported for some time in the DOM Level 2 specification and now available in IE9.

JavaScript

Equally important is the performance boost provided by the new Chakra JavaScript engine which basically blows away older versions of Internet Explorer and brings IE9 in line with modern browsers such as Chrome, Firefox and Opera. JavaScript development continues to become more complex and intricate so the importance of these performance enhancements can’t be understated. The Chakra engine interprets, compiles, and executes code in parallel and takes advantage of multiple CPU cores when available and the results are obvious by the greatly improved benchmark scores from the Webkit Sunspider JavaScript Benchmarks.

Chakra JavaScript Engine – WebKit SunSpider Benchmarks

Updated Developer Tools

Substantial work has been done to update the Internet Explorer Developer Tools. The built-in tools, usually found by pressing F12, provided quite a bit of capabilities but were missing key components that were essential to effective testing and debugging of client-side source code. With this update, the tools now include a much anticipated network traffic inspector, Console tab, CSS editing, and an improved JavaScript profiler.
The new Console tab is a welcome addition providing the ability to inspect script easily as well as receive important page-specific error and warning messages.

IE Developer Tools – Console Tab
Of the new features, the one that I’m most excited about is the network traffic inspector, mainly because the bulk of my application development involves Ajax-based requests.

IE Developer Tools – Network Performance of Specific Assets

IE Developer Tools – Network Request Information
I can now do such things as determine load times of specific assets or inspect my request/response headers, cookies and return values without the need for breaking out of the browser to a 3rd party application such as Fiddler or Charles.

Get to Using it Today

A lot of effort has gone into making Internet Explorer 9 Beta a better browser. There’s certainly more work to be done but the fact that we now have a version of IE that provides standards-based functionality and allows us to use the same markup across browsers is pretty hot.
To really appreciate what you can build with IE9, though, you need to just start digging into it. Microsoft has created the following sites to give developers the knowledge and inspiration they need to leverage IE9 to its fullest:

  • Beauty of the Web – Explore all of the new features of Microsoft’s latest browser and check out the cool demos built using the advanced features of Internet Explorer 9 Beta
  • Internet Explorer 9 Test Drive – This site breaks down the new, advanced features of Internet Explorer 9 Beta and lets you get a visual of what’s possible with each bit of functionality
  • Internet Explorer Guide for Developers – The developer documentation you’ll need to learn how about the specifics of Internet Explorer 9 Beta


It feels great to know that we’re on a path to being able to build truly feature-rich websites that will be easier to maintain and provide a more exciting experience to users. While we’ll still need to support older browsers for some time, the fact that all the major browser vendors are heading in the same direction is going to allow us to build some truly amazing things. I can’t wait!

Post originally taken from Here
READ MORE - IE9 is here, So.. what's in for you as a Developer