On Github danaonel / HTML5-canvas-presentation
<canvas> is an HTML5 element used to draw graphics, on the fly, via scripting (usually JavaScript). Source: http://www.w3schools.com/html/html5_canvas.aspThe <canvas> element has no drawing abilities of its own (it is only a container for graphics) - you must use a script to actually draw the graphics. It can, for instance, be used to draw graphs, make photo compositions or do simple (and not so simple) animations.
<canvas> element has only two attributes - width and height. These are both optional and can also be set using DOM properties. When no width and height attributes are specified, the canvas will initially be 300 pixels wide and 150 pixels high. The element can be sized arbitrarily by CSS, but during rendering the image is scaled to fit its layout size. Closing </canvas> is required by HTML5 standards.
Canvas can be styled by CSS, but the graphics inside the canvas will not be affected. Without any javascript, canvas is a transparent element.
Fallback content can be specified between opening <canvas> and closing </canvas>.
<canvas id="some-canvas" width="150" height="150">Fallback content</canvas>Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
In order to draw graphics on the canvas, we need to use javascript getContext() method. This returns an object that provides methods and properties for drawing on the canvas.
getContext() method takes one parameter, the type of context. There can be "2d" or "webgl" contexts. This presentation focuses on the "2d" context.
<canvas id="some-canvas" width="150" height="150">Fallback content</canvas> <script type="text/javascript"> var canvas = document.getElementById('tutorial'); var ctx = canvas.getContext('2d'); </script>
ctx now has access to all the drawing methods.
The fallback content is displayed in browsers which do not support <canvas>. Scripts can also check for support programatically by simply testing for the presence of the getContext() method.
<canvas id="some-canvas" width="150" height="150">Fallback content</canvas> <script type="text/javascript"> var canvas = document.getElementById('tutorial'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); // drawing code here } else { // canvas-unsupported code here } </script>
Canvas was first introduced by Apple for the Mac OS X Dashboard and later implemented in Safari and Google Chrome.
Supported browsers Unsupported browsers Internet Explorer 9 Internet Explorer 8 and earlier Firefox Opera Chrome Safari Gecko 1.8-based browsers, such as Firefox 1.51 unit in the grid corresponds to 1 pixel on the canvas. The top left corner corresponds to coordinate (0,0)). All elements are placed relative to this origin.
<canvas> only supports one primitive shape: rectangles. All other shapes must be created by combining one or more paths. We can use several path drawing functions which make it possible to compose very complex shapes. We can have linear paths, arcs and bezier curve paths.
There are three functions that draw rectangles on the canvas:
fillRect(x, y, width, height) Draws a filled rectangle. strokeRect(x, y, width, height) Draws a rectangular outline. clearRect(x, y, width, height) Clears the specified rectangular area, making it fully transparent.Each of these three functions takes the same parameters.x and y specify the position on the canvas (relative to the origin) of the top-left corner of the rectangle.width and height provide the rectangle's size.
All 3 functions draw a rectangle immediately on the canvas.
<canvas id="canvas" width="150" height="150"></canvas> <script type="text/javascript"> function draw() { var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.fillRect(25,25,100,100); ctx.clearRect(45,45,60,60); ctx.strokeRect(50,50,50,50); } } </script>
The fillRect() function draws a large black square 100 pixels on each side. The clearRect() function then erases a 60x60 pixel square from the center, and then strokeRect() is called to create a rectangular outline 50x50 pixels within the cleared square.
To draw arcs or circles, we use the arc() method.
arc(x, y, radius, startAngle, endAngle, anticlockwise) Draws an arc.x and y are the coordinates of the center of the circle on which the arc should be drawn.radius is self-explanatory. The startAngle and endAngle parameters define the start and end points of the arc in radians, along the curve of the circle. These are measured from the x axis. The anticlockwise parameter is a Boolean value which, when true, draws the arc anticlockwise; otherwise, the arc is drawn clockwise.
Angles in the arcfunction are measured in radians, not degrees. To convert degrees to radians you can use the following JavaScript expression: radians = (Math.PI/180)*degrees.
<canvas id="canvas" width="150" height="150"></canvas> <script type="text/javascript"> function draw() { var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(75,75,50,0,Math.PI*2,true); ctx.stroke(); // if we want a filled circle use ctx.fill() } } </script>
The first circle uses stroke(). The second one uses fill().
We can draw simple linear lines, bezier curves and other complex forms using path functions.
Before we start, there are a few methods used in drawing and manipulating lines, as well as rectangles and arcs. These methods allow drawing multiple lines and shapes in the same canvas, resulting in complex images.
First thing when we start drawing shapes, we have to call the beginPath(). Internally, paths are stored as a list of sub-paths (lines, arcs, etc) which together form a shape. Every time this method is called, the list is reset and we can start drawing new shapes.
function draw() { var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.beginPath(); // draw shapes methods } }
closePath() is optional and tries to close the shape by drawing a straight line from the current point to the start. If the shape has already been closed or there's only one point in the list, this function does nothing.
Alternatively we can use fill(). This function automatically closes the path and also fills in the shape with color or patterns. When you call fill(), any open shapes are closed automatically, so you don't have to call closePath().
function draw() { var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.beginPath(); // draw shapes methods ctx.closePath(); } }
What if we don't want a solid shape? We can use stroke() to draw an empty shape.stroke() draws the shape by stroking its outline.
function draw() { var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(75,75,50,0,Math.PI*2,true); // Draw a circle ctx.stroke(); } }
If we don't use fill() nor stroke(), the path or shape will be completely transparent.
Once we've drawn a line or shape and we want to add another one to the same canvas, we have to use moveTo() to set a different starting point. If we don't use moveTo, the new line or shape will be considered part of the initial shape.
moveTo(x, y) Moves the starting point for a path to the coordinates specified by x and y.
function draw() { var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(75,75,50,0,Math.PI*2,true); // Draw a circle ctx.moveTo(110,75); ctx.arc(75,75,35,0,Math.PI,false); // Draw 2nd circle ctx.moveTo(65,65); ctx.arc(60,65,5,0,Math.PI*2,true); // Draw 3rd circle ctx.moveTo(95,65); ctx.arc(90,65,5,0,Math.PI*2,true); // Draw 4th circle ctx.stroke(); } }
The difference between a quadratic Bézier curve and a cubic Bézier curve is that the quadratic curve has just one control point while a cubic Bézier curve uses two control points.
The x and y parameters in both of these methods are the coordinates of the end point.
Quadratic curve | Cubic curve
function draw() { var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); // Quadratric curves example ctx.beginPath(); ctx.moveTo(75,40); ctx.bezierCurveTo(75,37,70,25,50,25); ctx.bezierCurveTo(20,25,20,62.5,20,62.5); ctx.bezierCurveTo(20,80,40,102,75,120); ctx.bezierCurveTo(110,102,130,80,130,62.5); ctx.bezierCurveTo(130,62.5,130,25,100,25); ctx.bezierCurveTo(85,25,75,37,75,40); ctx.fill(); } }
Possible color values: "orange", "#FFA500", "rgb(255,165,0)", "rgba(255,165,0,1)"
function drawRedHeart() { var canvas = document.getElementById('red-heart'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.moveTo(75,40); ctx.bezierCurveTo(75,37,70,25,50,25); ctx.bezierCurveTo(20,25,20,62.5,20,62.5); ctx.bezierCurveTo(20,80,40,102,75,120); ctx.bezierCurveTo(110,102,130,80,130,62.5); ctx.bezierCurveTo(130,62.5,130,25,100,25); ctx.bezierCurveTo(85,25,75,37,75,40); ctx.fillStyle = "red"; ctx.strokeStyle = "#000000"; ctx.fill(); ctx.stroke(); } }
function drawRedHeart() { var canvas = document.getElementById('red-heart'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.fillStyle = "blue"; ctx.fillRect(50,50,100,50); ctx.beginPath(); ctx.moveTo(75,40); ctx.bezierCurveTo(75,37,70,25,50,25); ctx.bezierCurveTo(20,25,20,62.5,20,62.5); ctx.bezierCurveTo(20,80,40,102,75,120); ctx.bezierCurveTo(110,102,130,80,130,62.5); ctx.bezierCurveTo(130,62.5,130,25,100,25); ctx.bezierCurveTo(85,25,75,37,75,40); ctx.fillStyle = "rgba(255, 0, 0, 0.5)"; ctx.strokeStyle = "#000000"; ctx.fill(); ctx.stroke(); } }
function drawGradientHeart() { var canvas = document.getElementById('canvas'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); var lineargradient = ctx.createLinearGradient(0,0,150,150); lineargradient.addColorStop(0,'white'); lineargradient.addColorStop(1,'black'); ctx.beginPath(); ctx.moveTo(75,40); ctx.bezierCurveTo(75,37,70,25,50,25); ctx.bezierCurveTo(20,25,20,62.5,20,62.5); ctx.bezierCurveTo(20,80,40,102,75,120); ctx.bezierCurveTo(110,102,130,80,130,62.5); ctx.bezierCurveTo(130,62.5,130,25,100,25); ctx.bezierCurveTo(85,25,75,37,75,40); ctx.fillStyle = lineargradient; ctx.fillStroke = "red"; ctx.fill(); ctx.stroke(); } }
We can use images from scratch using new Image() method or we can use images that already exist on the page by using document.getElementById()
var img = new Image(); // Create new img element img.src = 'myImage.png'; // Set source path
When this script gets executed, the image starts loading.
Once the image loads, we can use drawImage() to render it on the canvas. Make sure the image loads before calling the method.
The image can also be scaled by using drawImage(image, x, y, width, height)
the image can be sliced by using drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
createPattern(image, "repeat")
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); // create new image object to use as pattern var img = new Image(); img.src = 'img/pattern.png'; img.onload = function(){ // create pattern var patern = ctx.createPattern(img,'repeat'); ctx.fillStyle = patern; ctx.fillRect(0,0,150,150); } }
Canvas text support is actually pretty good - you can control font, size, color, horizontal alignment, vertical alignment, and you can also get text metrics to get the text width in pixels. In addition, you can also use canvas transforms to rotate, stretch and even invert text. The text can use colors or patterns.
Canvas can take advantage of fonts defined in a CSS file using @font-face, and can fall back to multiple different fonts if the defined font is not available. It's important to know that Canvas text does not use CSS for styles.
function drawText() { var canvas = document.getElementById('canvas-text'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.font = "50px SapientSansLightItalic"; ctx.fillStyle = "#FF0000"; ctx.fillText ("Sapient Nitro", 50, 80); } }
function drawText() { var canvas = document.getElementById('canvas-text'); if (canvas.getContext){ var ctx = canvas.getContext('2d'); ctx.shadowOffsetX = 2; ctx.shadowOffsetY = 2; ctx.shadowBlur = 2; ctx.shadowColor = "rgba(0, 0, 0, 0.5)"; ctx.font = "50px SapientSansLightItalic"; ctx.fillStyle = "#FF0000"; ctx.fillText ("Sapient Nitro", 50, 80); } }
measureText() method will return some properties about that text, based on the current context settings (font face, size, and so on) in the form of a TextMetrics object. The TextMetrics object has only a single property: width. The width property of a TextMetrics object gives you the exact width in pixels of the text when rendered on the canvas. This can be very useful when attempting to center text.