HTML5 Canvas (Basics)

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

canvasThe 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().
contextThe 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 fillStylerectangle 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);

  1. strokeRect(x, y, width, height)
    can draw a strokeStyle lineWidth lineCap lineJoinrectangle 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 buttFlat head roundround head squaresquare head
lineWidth line width integer
lineJoin the way the lines intersect roundround bevelcross mittermiter
  1. 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
  1. 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;
}

  1. 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
  1. 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
  2. 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 fillStyleattributes to display text, and attributes strokeText(text, x, y, maxWidth)to strokeStylestroke 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 contextthe 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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325476717&siteId=291194637