CHAP 2. CANVAS API
WHAT IS CANVAS
Dynamically generate and render graphics, charts, images and
animations
SVG (Scalable Vector Graphics) vs. Canvas
Bitmap canvas
Images drawn on a canvas are final and not be resized
Objects drawn on a canvas are not part of the page’s DOM or any
namespace
SVG images can be scaled seamlessly at different resolutions and
allow hit detection
HTML5 Canvas API
It performs well because it does not have to store objects for every
primitive it draws
Relatively easy to implement the Canvas API
CANVAS
Element: <canvas></canvas>
Coordinates:
Browser
Details
Chrome
Supported in version 1.0 and
greater
Firefox
Supported in version 1.5 and
greater
Internet
Explorer
Not supported
Opera
Supported in version 9.0 and
greater
Safari
Supported in version 1.3 and
greater
CHECKING BROWSER SUPPORT
try {
document.createElement("canvas").getContext("2d");
document.getElementById("support").innerHTML =
"HTML5 Canvas is supported in your browser.";
} catch (e) {
document.getElementById("support").innerHTML =
"HTML5 Canvas is not supported
in your browser.";
}
CANVAS, DRAW LINE
A basic canvas with solid border
<canvas id="canvas" width="400" height="400" style="border: 1px
solid black"></canvas>
Get the canvas element and its context
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
Draw line
Prepare graph
context.beginPath();
context.moveTo(70, 140);
context.lineTo(140, 70);
Stroke graph onto the canvas
context.stroke();
Excerise
APPLYING TRANSFORMATIONS TO
DRAWINGS
APPLYING TRANSFORMATIONS TO
DRAWINGS
Get the canvas element and its context
Save the current drawing state
context.save();
Move to new coordinate
context.translate(70, 140);
Draw line
context.beginPath();
context.moveTo(0, 0);
context.lineTo(70, -70);
context.stroke();
Restore the old drawing state
context.restore();
Excerise
WORKING WITH PATHS
// Draw the tree canopy
context.beginPath();
context.moveTo(-25, -50);
context.lineTo(-10, -80);
context.lineTo(-20, -80);
context.lineTo(-5, -110;
context.lineTo(-15, -110);
// Top of the tree
context.lineTo(0, -140);
context.lineTo(15, -110);
context.lineTo(5, -110);
context.lineTo(20, -80);
context.lineTo(10, -80);
context.lineTo(25, -50);
// Close the path back to its start point
context.closePath();
context.stroke();
USING TRANSLATE
MOVE TREE TO SPECIFIC POSITION
function drawTree(context, x, y) {
context.save();
context.translate(x, y);
// Draw the tree canopy
context.beginPath();
context.moveTo(-25, -50);
context.lineTo(-10, -80);
context.lineTo(-20, -80);
context.lineTo( -5, -110);
context.lineTo(-15, -110);
// Top of the tree
context.lineTo(0, -140);
context.lineTo(15, -110);
context.lineTo(5, -110);
context.lineTo(20, -80);
context.lineTo(10, -80);
context.lineTo(25, -50);
// Close the path back to its start point
context.closePath();
context.stroke();
context.restore();
}
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
drawTree(context, 130, 250);
drawTree(context, 200, 300);
STROKE ST YLE
Line width
context.lineWidth = 4;
Corner style at path joins (round:圓角, bevel:斜角, miter)
context.lineJoin = 'round';
Line style at endpoints (round, square, butt :預設值)
context.lineCap = ‘square';
Stroke style
Change color
context.strokeStyle = '#663300';
FILL ST YLE
Fill Style
Change color
context.fillStyle = '#339900';
Background pattern
Fill the region inside all the closed paths
context.fill();
FILL RECTANGLE
// Change fill color to brown
context.fillStyle = '#663300';
// Fill a rectangle for the tree trunk
context.fillRect(-5, -50, 10, 50);
GRADIENT
Linear Gradient (漸層)
Usage
context.createLinearGradient (x0, y0, x1, y1)
x0, y0 - Line start
x1, y1 - Line end
gradient.addColorStop(offset, color)
offset - From 0.0 to 1.0
color - Use rgba() or HEX
Example
var trunkGradient = context.createLinearGradient (-5, -50, 5, -50);
trunkGradient.addColorStop(0, '#663300');
trunkGradient.addColorStop(0.4, '#996600');
trunkGradient.addColorStop(1, '#552200');
context.fillStyle = trunkGradient;
context.fillRect(-5, -50, 10, 50);
Radical Gradient
Usage
context.createRadicalGradient (x0, y0, r0, x1, y1, r1)
x0, y0, r0 – First circle center at (x0, y0) with radius r0
x1, y1, r1 – Second circle center at (x1, y1) with radius r1
DRAWING CURVES
Star ting Point: current location
context.quadraticCur veTo(ControlPointX, ControlPointY, EndPointX,
EndPointY);
Example:
context.save();
context.translate(-10, 350);
context.beginPath();
context.moveTo(0, 0);
context.quadraticCurveTo(170, -50, 260, -190);
context.quadraticCurveTo(310, -250, 410, -250);
context.lineWidth = 20;
context.strokeStyle = '#663300';
context.stroke();
context.restore();
BACKGROUND PATTERN
Usage
context.createPattern(image, repeat)
repeat - repeat, repeat-x, repeat-y, no-repeat
Example
var gravel = new Image();
gravel.src = "gravel.jpg";
gravel.onload = function () {
context.save();
context.translate(x, y);
context.beginPath();
context.moveTo(0, 0);
context.quadraticCurveTo(170, -50, 260, -190);
context.quadraticCurveTo(310, -250, 410, -250);
context.lineWidth = 20;
context.strokeStyle = context.createPattern(gravel, 'repeat');
context.stroke();
context.restore();
}
IMAGE
Load image
var img = new Image();
img.src = “bark.jpg”;
Confirm the image is loaded
img.onload = function(){
//Draw image onto canvas
}
Draw image onto canvas
context.drawImage(image, dx, dy)
context.drawImage(image, dx, dy, dw, dh)
context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
Example
var barkImg = new Image();
barkImg.src = "bark.jpg";
barkImg.onload = function () {
context.save();
context.translate(x, y);
// Draw trunk
context.drawImage(barkImg, -5, -50, 10, 50);
context.restore();
}
SCALE
Usage
context.scale(rx, ry);
rx – width scale ratio
ry – height scale ratio
Example
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.save();
context.translate(260, 500);
context.scale(2, 2);
drawTree(context);
context.restore();
ROTATE
Usage
context.rotate(angle)
angel can be express with Math.PI/180 * degree
Example
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.save();
context.translate(260, 500);
context.rotate(Math.PI/180 * 40);
drawTree(context);
context.restore();
TRANSFORM
context.transform (r x, sy, sx, r y, dx, dy)
rx – width scale ratio
sy – vertical shear
sx – horizontal shear
ry – height scale ratio
dx - horizontal moving
dy - vertical moving
Example
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.save();
context.translate(130, 250);
context.transform(1, 0, -0.5, 0.6, 0, 0);
context.scale(1, 0.6);
context.fillStyle = 'rgb(0, 0, 0, 0.2)';
context.fillRect(-5, -50, 10, 50);
createCanopyPath(context);
context.fill();
context.restore();
CANVAS TEXT
Usage
context.fillText(text, x, y, maxwidth)
context.strokeText(text, x, y, maxwidth)
Property
context.font = Font String
context.textAlign = start, end, left, right, center
context.textBaseLine = top, middle, bottom, …
Example
context.save();
context.font = '60px 標楷體';
context.fillStyle = '#996600';
context.textAlign = 'center';
context.fillText('快樂圖畫', 200, 60, 400);
context.restore();
SHADOWS
Usage
shadowColor – Any CSS Color
shadowOffsetX – Pixel Count
shadowOffsetY – Pixel Count
Shadowblur – Gaussian blur
Example
context.shadowColor = 'rgba(0, 0, 0, 0.2)';
context.shadowOffsetX = 15;
context.shadowOffsetY = -10;
context.shadowBlur = 2;
context.font = '60px 標楷體';
context.fillStyle = '#996600';
context.textAlign = 'center';
context.fillText('快樂圖畫', 200, 60, 400);
ANIMATION
Time-based Animation
When animating objects with JS, it is important that objects animate at
the same speed, without being affected by varying frame rates.
If game speed depends on computer processor will cause game run too
fast or too slow because computer processors speed is varying .
0 sec
10 FPS
1
5 FPS
1
1 sec
2
3
2
4
5
3
6
7
4
8
9
5
SEE ALSO
https://www.viget.com/articles/time-based-animation
http://creativejs.com/resources/requestanimationframe/
10
DRAW FRAMES
var fps = 15;
function draw() {
setTimeout(function() {
requestAnimationFrame(draw);
var now = new Date().getTime();
var delta = now - (time || now);
time = now;
// Drawing code goes here
var speed = 10;
var distance = speed * delta; // Increase ‘distance' by 10 units per millisecond
}, 1000 / fps);
}
PRACTICE: DRAWING TREE SHADOW
CYCLED EVERY 30 SECONDS
var fps = 15;
function draw() {
setTimeout(function() {
requestAnimationFrame(draw);
var now = new Date().getTime();
var delta = now - (time || now);
time = now;
// Drawing code goes here
// Clear canvas before drawing
context.clearRect(0, 0, canvas.width, canvas.height);
// Increase ‘distance' by 10 units per millisecond
var speed = 10;
var distance = speed * delta;
// Shadow Cycled every 30 secs. (sx range from -1 to 1)
var sx = time % (30 * 1000) / 5000 - 1;
drawTreeShadow(sx);
drawTree();
}, 1000 / fps);
}
SPIRITE ANIMATION
http://www.williammalone.com/articles/create -html5-canvasjavascript-sprite-animation/
GIF to Spirte
http://gif2sprite.com/
© Copyright 2026 Paperzz