In this post I want to show some sample on drawing vector objects on HTML Canvas element. Canvas element is new HTML element which allows us to write some graphics objects into the browser through the JavaScript code. This element is supported by FireFox, Safary and some other browsers. Internet Explorer does not support this element directly, but you can use excanvas library which implements Canvas functionality through VML. To read more about Canvas you may visit Mozilla Developer Center.
In the following sample I want to draw an image of boy (I call this image “The boy from |
Let’s define some auxiliary functions:
drawCircle function draws filled circle. Example: drawCircle(ctx, 100, 135, 50, "#00aa00"); | |
drawEllipse function draws ellipse with center in point (x,y), the smallest radius equal w and proportion between radiuses equal to scale. Ellipse is rotated with angle and filled with color. Example: drawEllipse(ctx, 100, 135, 50, 1.5, Math.PI/4, "#00aa00"); | |
drawArc function draws part of circle with center in point (x,y) radius w started at angle1 and finished at angle2. Boolean parameter fill describes should this part of circle be filled or striked. lineWidth means the width of line in the case of striking. Example: drawArc(ctx, 100, 135, 50, (3/4)*Math.PI, (1/4)*Math.PI, "#00aa00", false, 10); |
Next functions just draw some parts of the boy.
Here you can see the source HTML file with JavaScript code which draws an image of the boy.
<html>
<head>
</head>
<body>
<canvas id="Canvas1" width=200 height=270 style="border:1px solid red;">
</canvas>
<script>
window.onload = function() {
var canvas = document.getElementById("Canvas1");
var ctx = canvas.getContext('2d');
drawTrousers(ctx, 100, 200, 80, 20);
drawShoes(ctx, 85, 305, 115, 305);
drawJacket(ctx, 100, 180, 50, 60, "#7C4940");
drawHands(ctx, 100, 180, 45, "#CC0000");
drawCollar(ctx, 100, 120, 30, "#CC0000");
drawFace(ctx, 100, 100, 50, 45);
drawPompon(ctx, 100, 55, 10);
drawPartOfCap(ctx, 100, 300, 215, 10, "#CC0000");
drawMouth(ctx, 98, 155);
function drawHands(ctx, x, y, r, color) {
ctx.save();
drawCircle(ctx, x + r, y, 10, color);
drawCircle(ctx, x + r - 6, y - 4, 5, color);
drawCircle(ctx, x - r, y, 10, color);
drawCircle(ctx, x - r + 6, y - 4, 5, color);
ctx.restore();
}
function drawJacket(ctx, x, y, w, h, color) {
ctx.save();
ctx.scale(w/h, 1);
drawArc(ctx, x * (h/w), y, h, 0, Math.PI, color, true);
ctx.restore();
drawArc(ctx, x, y - h*2 + 8, h*2, Math.PI*(10/16), Math.PI*(6/16), color, false, w/3);
drawLine(ctx, x,y + 15,x,y-h, "#000000", 2);
drawLine(ctx, x - w*(0.6),y - h*(0.4),x - w*(0.7),y - h*(0.1),"#000000", 1);
drawLine(ctx, x + w*(0.6),y - h*(0.4),x + w*(0.7),y - h*(0.1),"#000000", 1);
}
function drawCollar(ctx, x, y, r, color) {
drawEllipse(ctx,x,y,r,1.3,0,color);
}
function drawTrousers(ctx, x, y, w, h) {
ctx.save();
ctx.translate(x,y);
ctx.fillStyle = "#000099";
ctx.fillRect(-w/2, -h/2, w, h);
ctx.restore();
}
function drawShoes(ctx, x, y, x1, y1) {
drawArc(ctx, x, y, 100, -Math.PI*(6/16), -Math.PI*(10/16), "#000000", true);
drawArc(ctx, x1, y1, 100, -Math.PI*(6/16), -Math.PI*(10/16), "#000000", true);
}
function drawMouth(ctx, x, y) {
drawArc(ctx, x, y, 25, -Math.PI*(6/16), -Math.PI*(9/16), "#000000", false, 1);
}
function drawLine(ctx, x1, y1, x2, y2, color, lineWidth) {
ctx.save();
ctx.strokeStyle = color;
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.stroke();
ctx.restore();
}
function drawFace(ctx, x, y, w, h) {
ctx.save();
ctx.translate(x,y);
ctx.scale(w/h, 1);
drawCircle(ctx, 0, 0, h, "#FEC6A5");
drawArc(ctx, 0, 0, h, - Math.PI/12, - (11/12)*Math.PI, "#000099", true)
// draw left eye
drawEllipse(ctx, w/4, w/10, 12, 1.2, Math.PI/4, "#FFFFFF");
drawCircle(ctx, w/6, w/10, 2, "#000000");
// draw right eye
drawEllipse(ctx, -w/4, w/10, 12, 1.2, -Math.PI/4, "#FFFFFF");
drawCircle(ctx, -w/6, w/10, 2, "#000000");
ctx.restore();
}
function drawPartOfCap(ctx, x, y, r, height, color) {
ctx.save();
ctx.lineCap = "round";
drawArc(ctx,x, y, r, -(15/35)*Math.PI, -Math.PI*(20/35), color, false, height);
ctx.restore();
}
function drawPompon(ctx, x, y, r) {
ctx.save();
ctx.translate(x,y);
ctx.lineWidth = r / 6;
ctx.lineCap = "round";
ctx.strokeStyle = "#CC0000";
for (var i = 0; i < 8; i++) {
ctx.rotate(Math.PI/8);
ctx.beginPath();
ctx.moveTo(-r, 0);
ctx.lineTo(r, 0);
ctx.stroke();
}
ctx.restore();
}
function drawArc(ctx, x, y, w, angle1, angle2, color, fill, lineWidth) {
ctx.save();
if (fill)
ctx.fillStyle = color;
else {
ctx.strokeStyle = color;
if (lineWidth) ctx.lineWidth = lineWidth;
}
ctx.translate(x,y);
ctx.beginPath();
ctx.arc(0, 0, w, angle1, angle2, true);
if (fill)
ctx.fill();
else
ctx.stroke();
ctx.restore();
}
function drawEllipse(ctx, x, y, w, scale, angle, color) {
ctx.save();
ctx.translate(x,y);
ctx.rotate(angle);
ctx.scale(scale, 1);
drawCircle(ctx, 0, 0, w, color);
ctx.restore();
}
function drawCircle(ctx, x, y, r, color) {
ctx.save();
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, r, 0, Math.PI*2, true);
ctx.fill();
ctx.restore();
}
}
</script>
</body>
</html>