canvas
DESCRIPTION
Talk about Canvas at Web Directions South ’09TRANSCRIPT
CanvasWeb Directions South 2009Dmitry Baranovskiy
HTML5 FTW!
“The canvas element represents a!resolution-dependent bitmap canvas, which can be used for
rendering graphs, game graphics, or other visual images on the fly”
HTML 5 Specification
Teenager of web
technologies
Awesome!What is
Awesome?
Draw!You can draw!
apiAPI is small & simple
HTML5HTML 5
HTML5HTML5
Howto?How to…
JavaScript
ContextContext
var canvas = document.getElementById("canvas"), context = canvas.getContext("2d");
context.save();context.restore();context.scale(x, y);context.rotate(angle);context.translate(x, y);context.transform(m11, m12, m21, m22, dx, dy);context.setTransform(m11, m12, m21, m22, dx, dy);
var a = context.globalAlpha;
context.globalAlpha = a * 0.5;
var b = context.globalCompositeOperation;
context.globalCompositeOperation = "xor";
context.strokeStyle = "#fc0";context.fillStyle = "#000";
var gradient = context.createLinearGradient(x1, y1, x2, y2);// orvar gradient = context.createRadialGradient(x1, y1, r1, x2, y2, r2);gradient.addColorStop(0 / 6, "red");gradient.addColorStop(1 / 6, "orange");gradient.addColorStop(2 / 6, "yellow");gradient.addColorStop(3 / 6, "green");gradient.addColorStop(4 / 6, "blue");gradient.addColorStop(5 / 6, "navy");gradient.addColorStop(6 / 6, "purple");context.fillStyle = gradient;
context.lineWidth = 2;
context.lineCap = "round";
context.lineJoin = "bevel";
context.miterLimit = 5;
context.shadowColor = "#000";
context.shadowOffsetX = 0;
context.shadowOffsetY = 3;
context.shadowBlur = 7;
primitivePrimitives
context.clearRect(x, y, width, height);context.fillRect(x, y, width, height);context.strokeRect(x, y, width, height);
pathsPaths
context.beginPath();context.closePath();
context.moveTo(x, y);context.lineTo(x, y);context.quadraticCurveTo(cpx, cpy, x, y);context.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);context.arcTo(x1, y1, x2, y2, radius);context.arc(x, y, radius, startAngle, endAngle, anticlockwise);context.rect(x, y, width, height);
context.fill();context.stroke();context.clip();context.isPointInPath(x, y);
textText
context.font = 'italic 400 12px/2 Palatino, »
Georgia, serif';
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("Web Directions", 100, 120);
context.strokeText("Canvas FTW", 100, 150, 140);
var metrics = context.measureText("How wide is »
this text?"),
width = metrics.width;
imagesImages
var image = new Image;
image.onload = function () {
context.drawImage(image, x, y);
// or
context.drawImage(image, x, y, w, h);
// or
context.drawImage(image, sx, sy, sw, sh,
x, y, w, h);
};
image.src = "graffiti.jpg";
var image = new Image;
image.onload = function () {
context.drawImage(image, x, y);
// or
context.drawImage(image, x, y, w, h);
// or
context.drawImage(image, sx, sy, sw, sh,
x, y, w, h);
};
image.src = "graffiti.jpg";
sx
sy
sh
sw
x
y
h
w
pixelsPixel Pushing
var data = context.createImageData(w, h);
// or
var data = context.createImageData(old_data);
var data = context.getImageData(x, y, w, h);
context.putImageData(data, dx, dy);
// or
context.putImageData(data, dx, dy, x, y, w, h);
var data = {
width: 100,
height: 100,
data: [0, 0, 0, 0, 255, 128, 0, 255, … , 0]
};
var data = {
width: 100,
height: 100,
data: [0, 0, 0, 0, 255, 128, 0, 255, … , 0]
};
var data = {
width: 100,
height: 100,
data: [0, 0, 0, 0, 255, 128, 0, 255, … , 0]
};
R G B A
not!What is not Awesome?
uglyAPI is ugly
1by1Setting attributes one by one
context.lineWidth = 2;
context.lineCap = "round";
context.lineJoin = "bevel";
context.miterLimit = 5;
context.shadowColor = "#000";
context.shadowOffsetX = 0;
context.shadowOffsetY = 3;
context.shadowBlur = 7;
context.setAttr({
lineWidth: 2,
lineCap: "round",
lineJoin: "bevel",
miterLimit: 5,
shadowColor: "#000",
shadowOffsetX: 0,
shadowOffsetY: 3,
shadowBlur: 7
});
pain!Coding paths is painful
context.beginPath();context.moveTo(x, y);context.lineTo(x, y);context.quadraticCurveTo(cpx, cpy, x, y);context.bezierCurveTo(c1x, c1y, c2x, c2y, x, y);context.arcTo(x1, y1, x2, y2, radius);context.arc(x, y, radius, startAngle, endAngle, anticlockwise);context.rect(x, y, width, height);context.closePath();context.fill();
context.beginPath() .moveTo(x, y) .lineTo(x, y) .quadraticCurveTo(cpx, cpy, x, y) .bezierCurveTo(c1x, c1y, c2x, c2y, x, y) .arcTo(x1, y1, x2, y2, radius) .arc(x, y, radius, startAngle, endAngle, anticlockwise) .rect(x, y, width, height) .closePath() .fill();
var path = ["move", x, y,
"line", x, y,
"quadratic", cpx, cpy, x, y,
"arc", x, y, radius, startAngle,
endAngle, anticlockwise];
context.path(path).close().fill();
context.path(["move", 10, 10, "line", 50,
50]).close().fill();
no wayNo way to store path
more!Not enough primitives
supportBad support
89%
81%
76%
74%
Zero
HTML 5
Thank You
Photos used in this presentation:http://www.flickr.com/photos/garryknight/2390411392/http://www.flickr.com/photos/livenature/233281535/http://www.flickr.com/photos/yoadolescente/3212368604/http://www.flickr.com/photos/andreassolberg/433734311/http://www.flickr.com/photos/cassidy/67331975/http://www.flickr.com/photos/b-tal/93425807/http://www.flickr.com/photos/pefectfutures/163853250/http://www.flickr.com/photos/streetart-berlin/3746020273/http://www.flickr.com/photos/streetart-berlin/3954856553/http://www.flickr.com/photos/streetart-berlin/3947360186/http://www.flickr.com/photos/streetart-berlin/3949549099/http://www.flickr.com/photos/streetart-berlin/3949546871/http://www.flickr.com/photos/streetart-berlin/3926942710/http://www.flickr.com/photos/streetart-berlin/3834021290/