HTML5-10-Canvas

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/