Recently, I am learning the new elements of HTML5 <canvas>
, I will share some basic knowledge and small examples, and finally use <canvas>
a js library to draw a simple chart (bar chart, line chart or pie chart), and I will update one or two articles~
Below we will Let's get started~
Confirm width and height
We should first specify <canvas>
the width and height properties of the tag, the canvas, and add fallbacks between the opening and closing tags:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="canvas" width="500" height="500">Canvas is not supported.</canvas>
</body>
</html>
get drawing context
canvas
The method to call getContext()
, this method takes one parameter, the name of the context:
var canvas = document.getElementById("canvas");
if(canvas.getContext) {
var context = canvas.getContext("2d")
}
In the above example, when we call the getContext()
method, we first check whether it exists. This is because some browsers also create a DOM object when they encounter tags outside the HTML specification. For example, we try the following code in Chrome:
<ppp id="ppp"></ppp>
document.getElementById("ppp");
//<ppp id="ppp"></ppp>
Therefore, even if the current browser is not compatible with the canvas element in the HTML specification, the DOM object will also be created, but it does not exist in it getContext()
.
context
The context object contains a series of properties and methods required for drawing. When reading this article, remember to distinguish between properties and methods. Changing properties will affect subsequent drawing effects, and calling methods is often one-time.
Draw simple 2D graphics
Coordinate origin
The coordinates of the 2D context start at the upper left corner by default, and the origin coordinate is (0, 0), and the translate(x, y)
coordinate origin can be changed by using it.
filling
Fill is to fill the specified area with the specified style, such as color, gradient or image. The corresponding context attribute is fillStyle
, the default value is #000000
, for example:
context.fillStyle = "orange";
stroke
Stroke is to draw a line of a specified style on the edge of a specified area, such as:
context.strokeStyle = "grey";
draw rectangle
Rectangle is the only shape that can be directly spoken in 2D context, all others need to draw a path, you can use 3 methods to draw rectangle directly.
1. fillRect(x, y, width, height)
can draw a fillStyle
rectangle with a specified fill style, such as:
context.translate(100, 100)
context.fillStyle = "#99cccc";
context.fillRect(-100, -50, 200, 100);
context.fillStyle="#3399cc";
context.fillRect(-60, -30, 120, 60);
- strokeRect(x, y, width, height)
can draw astrokeStyle
lineWidth
lineCap
lineJoin
rectangle whose stroke style is specified by other attributes, such as:
context.strokeStyle = "#99cccc";
context.lineWidth = "50";
context.lineJoin = "bevel";
context.strokeRect(0, 0, 400, 200);
property name | meaning | value |
---|---|---|
lineCap | shape of the end of the line | butt Flat head round round head square square head |
lineWidth | line width | integer |
lineJoin | the way the lines intersect | round round bevel cross mitter miter |
- clearRect(x, y, width, height)
can clear the specified area on the canvas, such as the two rectangles in the first example, we will clear a small piece in the middle:
context.translate(100, 100)
context.fillStyle = "#99cccc";
context.fillRect(-100, -50, 200, 100);
context.fillStyle="#3399cc";
context.clearRect(-60, -30, 120, 60);
draw path
Using paths, we can draw more complex graphics. Before starting to draw, first execute:
context.beginPath();
When you finish drawing, execute:
context.closePath();
Here are a few ways to draw a path:
straight line
lineTo(x, y)
, draws a line from the current cursor to (x, y).
move cursor
moveTo(x, y)
Move the cursor to (x, y) without drawing a line during the move. for example:
context.beginPath();
context.moveTo(10, 10);
context.lineTo(50, 40);
context.moveTo(50, 50);
context.lineTo(100, 90);
context.stroke();
context.closePath();
arc or circle
- arc(x, y, radius, startAngle, endAngle, counterclockwise)
draws an arc with (x, y) as the center and radius as the radius from startAngle to endAngle, where startAngle and endAngle are expressed in radians, when counterclockwise is false, the Draw an arc clockwise, and vice versa, draw an arc counterclockwise.
var canvas = document.getElementById("canvas");
if(canvas.getContext) {
var context = canvas.getContext("2d");
context.beginPath();
context.arc(400, 400, 50, arcUnit()*30, arcUnit()*180, false);
context.stroke();
}
function arcUnit() {
return Math.PI/180;
}
- The arcTo(startX, startY, endX, endY, radius)
arcTo()
method will use the angle formed by the current coordinates, the starting point (startX, startY) and the end point (endX, endY) to draw a section tangent to both sides of the angle And an arc on a circle with radius radius. The starting point of the arc is the tangent point between the edge of the current coordinate and the circle, the end point of the arc is the tangent point between the edge where the end point (endX, endY) is located and the circle, and the drawn arc is the one with the shortest length between the two tangent points. arc. Additionally, if the current endpoint is not (startX,startY), the arcTo() method will also add a line segment from the current endpoint to (startX,startY).
If you still remember high school math, we should be able to guess that there are roughly three situations in which arcs are drawn using this method:
** There is only one radius that can make the ends of the arc exactly at the start and end
** If the radius is too large, draw No arc
** If the radius is small, there must be a straight line from the current endpoint to the starting point.
Let's give three examples:
first define some general
var context = canvas.getContext("2d");
var currentPoint = {
x: 0,
y: 0
};
var startPoint = {
x: 50,
y: 50
};
var endPoint = {
x: 100,
y: 0
};
Then draw the reference line
context.moveTo(currentPoint.x, currentPoint.y);
context.lineTo(startPoint.x, startPoint.y);
context.lineTo(endPoint.x, endPoint.y);
context.strokeStyle = "red";
context.stroke();
draw the first arc
context.moveTo(currentPoint.x, currentPoint.y);
context.arcTo(startPoint.x, startPoint.y, endPoint.x, endPoint.y, 80);
context.strokeStyle = "grey";
context.stroke();
context.arcTo(startPoint.x, startPoint.y, endPoint.x, endPoint.y, 120);
context.arcTo(startPoint.x, startPoint.y, endPoint.x, endPoint.y, 40);
curve
- Quadratic Bezier Curve
quadraticCurveTo(cpX, cpY, x, y)
The above method can draw a Bezier curve from the current position to (x, y) with (cpX, cpY) as the control point - Cubic Bezier Curve
bezierCurveTo(cpX1, cpY1, cpX2, cpY2, x, y)
The above method can draw a Bezier curve from the current position to (x, y) with (cpX1, cpY1) and (cpX2, cpY2) as control points.
The drawing of the quadratic Bezier and the third Bezier involves relatively complex mathematical operations, which the author ignores here...
Of course, most front-end people may be the same as the author, only hoping to draw a beautiful curve, and Don't care about the implementation details, then what kind of curve is generally considered to be a beautiful curve:
1. Symmetrical curve
2. There is a moderate radian
According to the above rules, we write a tool method:
function drawCurvePath( ctx, start, end, curveness ) {
var cp = [
( start.x + end.x ) / 2 - ( start.y - end.y ) * curveness,
( start.y + end.y ) / 2 - ( end.x - start.x ) * curveness
];
ctx.moveTo( start.x, start.y );
ctx.quadraticCurveTo(
cp[ 0 ], cp[ 1 ],
end.x, end.y
);
ctx.stroke();
}
The above reference is to draw a curve animation with canvas - in-depth understanding of Bezier curves , you can go to learn more in-depth Bezier curve drawing methods.
rectangle
Use rect(x, y, width, height)
to draw a rectangular path with upper left corner coordinates (x, y), width width, and height height.
context.rect(300, 300, 100, 200);
context.stroke();
draw text
Before drawing this article, if necessary, we should first specify several properties of the context, such as:
context.font = "bold 14px Arial"; // 格式同css中指定字体样式
context.textAlign = "center"; // start end center left right
context.textBaseline = "middle"; // top hanging middle alphabetic ideographic bottom
fillText(text, x, y, maxWidth)
Use fillStyle
attributes to display text, and attributes strokeText(text, x, y, maxWidth)
to strokeStyle
stroke text.
Use measureText(text)
method to get the width of the text. If we don't know whether the specified width is enough to display a piece of text under the current font setting, we can use the following method:
var fontSize = 50;
var maxWidth = 100;
context.font = "bold " + fontSize+"px Arial";
var text = "Hello World!";
while(context.measureText(text).width > maxWidth) {
fontSize--;
context.font = "bold " + fontSize+"px Arial";
}
context.fillText(text, 50, 50, maxWidth);
transform
rotate
rotate(angle)
context.rotate(Math.PI/4)
context.fillText(text, 50, 50, maxWidth);
zoom
scale(scaleX, scaleY)
context.scale(1.2, 1.2);
context.fillText(text, 50, 50, maxWidth);
context.scale(0.5, 0.5);
context.fillText(text, 50, 50, maxWidth);
Move the coordinate origin
translate(x, y)
If we want to draw a symmetrical figure, moving the origin of the coordinates will greatly simplify the calculation of the coordinates.
matrix transformation
Use transform(scaleX,skewX,skewY,scaleY,transX,transY)
can perform matrix transformation. In fact, the three methods mentioned above are essentially calling matrix transformation. As can be seen from the parameter names, they represent the scaling in the X-axis direction, the scaling in the Y-axis direction, and the oblique cutting in the X-axis direction. , the chamfer in the Y-axis direction, the offset in the X-axis direction, and the offset in the Y-axis direction. The default values are 1 0 0 1 0 0 respectively.
We now use transform()
the three methods we redefined before:
rotate
function rotate (ctx, degree) {
var unit = Math.PI/180;
ctx.transform(Math.cos(degree*unit),Math.sin(degree*unit),-Math.sin(degree*unit),Math.cos(degree*unit),0,0)
}
scale
function scale (ctx, scale) {
ctx.transform(scale.x, 0, 0, scale.y, 0, 0);
}
translate
function translate (ctx, translate) {
ctx.transform(1, 0, 0, 1, translate.x, translate.y);
}
We now draw a piece of text, first translate (50, 50), then scale 2 times, and finally rotate 30 degrees.
context.fillText(text, 50, 50, maxWidth);
translate(context, {x: 50, y: 50});
scale(context, {x: 2, y: 2});
rotate(context, 30);
context.fillText(text, 50, 50, maxWidth);
Each execution transform()
is based on the previous result, not the initial state. In many cases, what we want to execute is to rotate, translate or zoom based on the initial state, not the previous state. At this time, we can use setTransfrom(scaleX,skewX,skewY,scaleY,transX,transY)
this method. Set the transformation matrix, and then execute transform()
.
For more details, please refer to HTML5 Canvas Drawing Tutorial 26: Using transform to achieve displacement, scaling, rotation, etc.
draw the image
Use drawImage(image, x1, y1, width1, height1, x2, y2, width2, height2)
to draw the specified part of the image to the specified position on the canvas according to the specified size.
parameter | meaning |
---|---|
image | Image to draw, either HTMLImageElement or canvas |
x1 | the x coordinate of the source image |
y1 | the y coordinate of the source image |
width1 | the width of the source image |
height1 | the height of the source image |
x2 | the x-coordinate of the canvas |
y2 | the y coordinate of the canvas |
width2 | The width of the image displayed on the canvas |
height2 | The height at which the image is displayed on the canvas |
draw shadow
If we want to shadow a shape or path, we need to set context
the following properties of the object before drawing:
Attributes | meaning |
---|---|
shadowColor | shadow color |
shadowOffsetX | x-axis offset |
shadowOffsetY | y-axis offset |
shadowBlur | blurred pixels |
context.shadowColor = "grey";
context.shadowOffsetX = "20";
context.shadowBlur = "5";
context.fillText(text, 50, 50, maxWidth);
Gradient
Linear Gradient
Use createLinearGradient(startX, startY, endX, endY)
to create a linear gradient, this method confirms the start and direction of the gradient, and then we addColorStop(position, color)
add the color of the gradient through, position is a number from 0 to 1. Let's draw a stripe gradient that I like very much:
var grad = context.createLinearGradient(50, 50, 200, 200)
grad.addColorStop(0, "grey");
grad.addColorStop(0.3, "grey");
grad.addColorStop(0.3, "red");
grad.addColorStop(0.5, "red");
grad.addColorStop(0.5, "orange");
grad.addColorStop(0.7, "orange");
context.fillStyle = grad;
context.fillRect(50, 50, 150, 150);
radial gradient
Use to createRadialGradient(centerX1, centerY1, radius1, centerX2, centerY2, radius2)
create radial gradients.
image repeat
Use createPattern(image, repeatType)
can draw repeated images, used to fill or stroke, the first parameter is the HTMLImageElement or canvas or video to be repeated, the second parameter indicates how to repeat the image, optionalrepeat
repeat-x
repeat-y
no-repeat