Web Programming 1 Packet #5: Canvas and JavaScript Name: Objectives: By the completion of this packet, students should be able to: use JavaScript to draw on the canvas element Canvas Element. This is a new html element that was introduced as part of html 5. You use this element in the body of a page. <!DOCTYPE html><html> <head> <meta charset="utf-8" ><title>canvas</title> <style> canvas{ border:black thin solid; background-color: #FCF; } </style> </head> <body> <h1>canvas</h1> <canvas id="cv" width="200" height="200">your browser does not support the canvas element. </canvas> <p>there is a canvas above this paragraph.</p> </body> </html> Important. 1) Any text between the opening and closing canvas tags are only displayed if the browser does NOT recognize the canvas tags. In other words, old browsers will display the text and not the element. 2) The width and height attributes in the opening tag determine the coordinate space. 3) The purpose of the canvas is to define an area where the things can be drawn using JavaScript. Without JavaScript there is no reason to have a canvas element. There are different ways to draw on a canvas element. We will only be looking at ways to use JavaScript to draw on the canvas. There are other tools (e.g. SVG and WebGL) that have certain advantages and disadvantages but we will not be discussing those technologies. Page 1
Drawing On a Canvas. The following code simply expands on the previous code. <!DOCTYPE html> <html> <head> <meta charset="utf-8" ><title>canvas</title> <style> #cv{ border:thin black solid; background-color:#fcf; } </style> <script> function draw() { var canvas = document.getelementbyid( "cv" ); var context = canvas.getcontext('2d'); context.beginpath(); // starts a list of instructions context.strokestyle = "#ff00000"; // can define a color, gradient, or pattern context.linewidth = 5; // line width in pixels context.moveto( 5, 5 ); // starts sub-path at x = 5, y = 5 context.lineto( 50, 200 ); // adds point to the sub-path and a line to prev. point context.lineto( 100, 0 ); // adds point to the sub-path and a line to prev. point context.closepath(); // adds line to the start and closes the path } </script> </head> context.stroke(); // draws the sub-path using the current stroke <body onload="draw()"> <h1>canvas</h1> <canvas id="cv" width="200" height="200">this browser does not support the canvas element. Please upgrade your browser.</canvas> <p>there is a canvas above this paragraph.</p> </body> -y </html> Coordinate Space. The upper left hand corner of the canvas is the origin. The size is 200 by 200 because of the width and height attributes in the canvas tag. -x 200 +x Anything draw outside of this coordinate space will not be displayed. 200 +y Page 2
Exercise 1. Create the page to the right. There is an h1 element followed by a 300 by 300 pixel canvas element. Write a function that draws 4 black lines to each of the midpoints of the edges of the canvas. The lines should be 10 pixels wide. Then, in the same function, draw 4 white lines that follow the same path except these lines are only 1 pixel wide. Hint. You are making two paths and will need to call stroke() for each path. This image should be displayed when the page is loaded. Use CSS to change the canvas s background color. Exercise 2. Create the page to the right. There is a canvas element that has a width of 300 and a height of 100. Follow these guidelines: Create two paths: one for the green lines and one for the black lines. The green lines are 20 pixels wide and the black lines are 1 pixel wide. The coordinates are all multiples of 25. The black lines have the same coordinates as the green lines. This image should be displayed when the page is loaded. Notice that when the width of a line is greater than 1, it spreads to the left and right of its center. There is a property, linecap, that controls how the end of a line looks. It has three possible values: butt, round, or square. Here s some sample code. var canvas = document.getelementbyid( "cv" ); var context = canvas.getcontext('2d'); context.linecap = "round"; // or butt or square Change your code for exercise 2 to produce the other two figure. Obviously the middle figure is round. Is the top figure butt and the bottom square or vice versa? Which is the default value? Page 3
Quick Review. Here are the basic steps for drawing on the canvas. Code Explanation var can = document.getelementbyid( " " ); Get a reference to the canvas. var ctx = can.getcontext('2d'); getcontext returns an object that we use to ctx.moveto(, ); ctx.lineto(, );... ctx.closepath(); // optional draw on the canvas. Define a path which is a series of points. Right now all we know about is moveto and lineto but there are other methods we can use. closepath draws a straight line from the last point to the first point in the path ctx.strokestyle = "color"; Define line color. Default is black. ctx.linewidth = 5; Define line width. ctx.linecap = "round/square/butt"; Define how the lines are capped Draw (aka render) the path. You may describe the line then the path, or vice versa, but call stroke last. NEW. In addition to the stroke to be used with a path, you can also define the fill. For example: var can = document.getelementbyid( "some_id" ); var ctx = can.getcontext('2d'); // the path is a triangle ctx.moveto( 100, 100 ); ctx.lineto( 150, 150 ); ctx.lineto( 50, 150 ); ctx.closepath(); ctx.fillstyle = "#990099"; // fill color ctx.fill(); // renders, aka draws, the fill ctx.strokestyle = "#AAAAAA"; // line color ctx.linewidth= 5; // line width // render the line NOTE. It makes a difference whether you call fill() then stroke() or stroke() then fill(). Exercise 3. Create the page to the right. The canvas is 100 by 200. Use CSS to color the canvas s background. Your figure doesn t have to look exactly like this but it should look at least as good. Use different colors for the stroke and the fill. Page 4
Rectangles. To draw the outline of a rectangle: var c=document.getelementbyid("mycanvas"); var ctx=c.getcontext("2d"); ctx.strokerect( 20, 20, 150, 100 ); - sample code from www.w3schools.com/tags/canvas_strokerect.asp strokerect() both defines the rectangle and draws the stroke around it. The first two numbers are the x/y coordinates of the rectangle s upper left hand corner. The last two numbers are the rectangle s width and height. All units are in pixels. Similarly, to draw a filled rectangle: var c=document.getelementbyid("mycanvas"); var ctx=c.getcontext("2d"); ctx.fillrect(20,20,150,100); - sample code from www.w3schools.com/tags/canvas_fillrect.asp Notice that these methods do NOT require you to construct a path. Exercise 4. Create the page to the right. The canvas is 300 by 200. Your house does not have to look exactly like mine but: the sky is blue the grass is green. there are four rectangles. Exercise 5. Create the page to the right. The canvas is 250 by 250. Use CSS to make the canvas s background color red. Draw exactly four squares (and nothing else) where each square is 100 by 100. Yes, I know that the figure only shows two squares. You have to figure out drawing four squares yields this figure. The strokes are black and 4 pixels wide. Use the following values for the colors of the fills: #333333 #666666 #999999 #CCCCCC Page 5
Arcs and Circles. The arc() method can be used to draw a circle or a portion of a circle. arc( x, y, radius, starting angle, ending angle, true/false ) x, y: coordinates of the center of the circle. starting angle where the arc starts as measured in radians. 0 radians is at 3 o clock. 0.5*pi radians is 6 o clock, pi radians is 9 o clock, and so on. See www.w3schools.com/tags/canvas_arc.asp for more information. ending angle true/false where the arc ends as measured in radians from the right optional. If true then the drawing is counter-clockwise. False indicates clockwise. False is the default value. Here are some examples. Assume they all start with following two lines: var c=document.getelementbyid("mycanvas"); var ctx=c.getcontext("2d"); The canvas is 100 by 100 with a gray background. ctx.arc( 50, 50, 25, 0, Math.PI, true ); ctx.arc( 50, 50, 25, 0, Math.PI, false ); ctx.arc( 50, 50, 50, 0, 2* Math.PI ); ctx.arc( 50, 50, 25, 0, 2* Math.PI ); ctx.fillstyle = "red"; ctx.fill(); ctx.linewidth = 4; ctx.arc( 25, 50, 25, 1.5* Math.PI, 0, false ); ctx.arc( 75, 50, 25, Math.PI, 0.5*Math.PI, true ); ctx.arc( 50, 30, 25, 0, Math.PI, true ); ctx.lineto( 50, 95 ); ctx.closepath(); ctx.linewidth = 3; ctx.fillstyle = "green"; ctx.fill(); Note. When drawing a circle, the starting and ending angles simply need to be 2 pi or more apart. Page 6
Exercise 6. Create the page to the right. The canvas is 200 by 200. Use CSS to change the canvas s background color. You may use more than one path. Exercise 7. Create the page to the right. The canvas is 300 by 150. Use CSS to change the canvas s background color. Use only one path. Change the thickness of the stroke and the fill color. Exercise 8. Create the page to the right. The canvas is 250 by 250. Use CSS to change the canvas s background color. Exercise 8. Create the figure shown below. There is no border around the canvas and its background is white by default. You pick the canvas size. My function is about 30 lines long. Page 7