Easy Tutorial
❮ Go Channel Intro Android Tutorial Date Time 1 ❯

This is an English translation of the provided Chinese text. Please find the translation below:


All You Need is This Article to Learn HTML5 Canvas

Category Programming Techniques

I. Introduction to Canvas

The <canvas> element is a new addition in HTML5, an HTML element that allows for drawing graphics via scripting (typically JavaScript). It can be used to create photo albums or even simple (not so simple) animations, and can even be used for real-time video processing and rendering.

It was initially introduced by Apple internally with their MacOS X WebKit for applications to use dashboard-like components and by the Safari browser. Later, it was adopted by browsers with the Gecko engine (especially Mozilla and Firefox), Opera, Chrome, and the Web Hypertext Application Technology Working Group suggested its use for next-generation web technologies.

The Canvas is defined by HTML code with height and width attributes, creating a drawable area. JavaScript code can access this area, similar to other common two-dimensional APIs, using a complete set of drawing functions to dynamically generate graphics.

Mozilla's program has supported <canvas> since Gecko 1.8 (Firefox 1.5), Internet Explorer has supported <canvas> since IE9. Chrome and Opera 9+ also support <canvas>.


II. Basic Usage of Canvas

<canvas id="tutorial" width="300" height="300"></canvas>

2.1 The <canvas> Element

The <canvas> looks similar to the <img> tag, except that <canvas> only has two optional attributes, width and height, and does not have src or alt attributes.

If the width and height attributes are not set for <canvas>, the default width is 300 and height is 150, both in pixels. You can also use CSS properties to set the width and height, but if the aspect ratio is inconsistent with the initial ratio, it will appear distorted. Therefore, it is recommended never to use CSS properties to set the width and height of <canvas>.

Fallback Content

Since some older browsers (especially IE browsers before IE9) or browsers that do not support the HTML element <canvas>, you should always display alternative content on these browsers.

Browsers that support <canvas> will only render the <canvas> tag and ignore the fallback content. Browsers that do not support <canvas> will directly render the fallback content.

Replace with text:

<canvas>
    Your browser does not support canvas, please upgrade your browser.
</canvas>

Replace with <img>:

<canvas>
    <img decoding="async" src="./beauty.jpg" alt="">
</canvas>

The closing tag </canvas> must not be omitted.

Unlike the <img> element, the <canvas> element requires a closing tag (</canvas>). If the closing tag is missing, the rest of the document will be considered fallback content and will not be displayed.

2.2 Rendering Context (The Rendering Context)

<canvas> creates a canvas of a fixed size and exposes one or more rendering contexts (brushes), using the rendering context to draw and process the content to be displayed.

We focus on studying the 2D rendering context. Other contexts are not studied for now, for example, WebGL uses a 3D context based on OpenGL ES ("experimental-webgl").

var canvas = document.getElementById('tutorial');
// Get the 2D context object
var ctx = canvas.getContext('2d');

2.3 Detecting Support

var canvas = document.getElementById('tutorial');

if (canvas.getContext){
  var ctx = canvas.getContext('2d');
  // drawing code here
} else {
  // canvas-unsupported code here
}

2.4 Code Template

Example

<canvas id="tutorial" width="300" height="300"></canvas>
<script type="text/javascript">
function draw(){
    var canvas = document.getElementById('tutorial');
    if(!canvas.getContext) return;
      var ctx = canvas.getContext("2d");
      // Start of code
}
draw();
</script>

2.5 A Simple Example

The following example draws two rectangles:

Example

<canvas id="tutorial" width="300" height="300"></canvas>
<script type="text/javascript">
function draw(){
    var canvas = document.getElementById('tutorial');
    if(!canvas.getContext) return;
    var ctx = canvas.getContext("2d");
    ctx.fillStyle = "rgb(200,0,0)";
    // Draw a rectangle

1. `arc(x, y, r, startAngle, endAngle, anticlockwise)`: With the center at `(x, y)`, and `r` as the radius, it starts from the `startAngle` radians to the `endAngle` radians. `anticlockwise` is a boolean value, `true` represents counterclockwise, and `false` represents clockwise (default is clockwise).

Note:

-

The degrees here are in radians.

-

`0` radians refers to the positive direction of the `x` axis.


radians = (Math.PI/180) * degrees // Convert degrees to radians


2. `arcTo(x1, y1, x2, y2, radius)`: Draws an arc segment based on the given control points and radius, and then connects the two control points with a straight line.

## Arc Example 1

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.arc(50, 50, 40, 0, Math.PI / 2, false); ctx.stroke(); } draw();



## Arc Example 2

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.arc(50, 50, 40, 0, Math.PI / 2, false); ctx.stroke();

ctx.beginPath();
ctx.arc(150, 50, 40, 0, -Math.PI / 2, true);
ctx.closePath();
ctx.stroke();

ctx.beginPath();
ctx.arc(50, 150, 40, -Math.PI / 2, Math.PI / 2, false);
ctx.fill();

ctx.beginPath();
ctx.arc(150, 150, 40, 0, Math.PI, false);
ctx.fill();

} draw();



## Arc Example 3

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(50, 50); // Parameters 1 and 2: Control point 1 coordinates Parameters 3 and 4: Control point 2 coordinates Parameter 5: Arc radius ctx.arcTo(200, 50, 200, 200, 100); ctx.lineTo(200, 200) ctx.stroke();

ctx.beginPath();
ctx.rect(50, 50, 10, 10);
ctx.rect(200, 50, 10, 10)
ctx.rect(200, 200, 10, 10)
ctx.fill()

} draw();



Explanation of the `arcTo` method:

This method can be understood in this way. The drawn arc is determined by two tangents.

The 1st tangent: The straight line determined by the starting point and control point 1.

The 2nd tangent: The straight line determined by control point 1 and control point 2.

​**In fact, the drawn arc is an arc that is tangent to these two lines.**

### 4.5 Drawing Bezier Curves

**4.5.1 What is a Bezier Curve**

A Bezier curve, also known as a Bézier curve or Bézout curve, is a mathematical curve used in two-dimensional graphic applications.

General vector graphics software uses it to draw curves precisely. Bézier curves consist of line segments and nodes, where nodes are movable pivot points, and line segments act like stretchable rubber bands. The pen tool we see in drawing tools is used for creating such vector curves.

Bezier curves are quite important parametric curves in computer graphics, and there are also Bezier curve tools in some more mature bitmap software, such as Photoshop. In Flash4, there was no complete curve tool, but Flash5 has already provided a Bezier curve tool.

The Bezier curve was widely published by French engineer Pierre Bézier in 1962, who used Bezier curves to design the body of cars. The Bezier curve was originally developed by Paul de Casteljau in 1959 using the de Casteljau algorithm to calculate Bézier curves in a stable numerical manner.

A first-degree Bezier curve is actually a straight line.



Second-degree Bezier curve





Third-degree Bezier curve





**4.5.2 Drawing Bezier Curves**

Drawing a quadratic Bezier curve:

quadraticCurveTo(cp1x, cp1y, x, y)


Description:

- Parameters 1 and 2: Control point coordinates

- Parameters 
ctx.lineWidth = 20;
ctx.stroke()


### 2. lineCap = type

Line end style.

There are 3 values:

-

`butt`: The line ends with a flat end.

-

`round`: The line ends with a round end.

-

`square`: The line ends with a square end, but an additional rectangle area is added with the same width as the line and half the height of the line thickness.


var lineCaps = ["butt", "round", "square"];

for (var i = 0; i < 3; i++){ ctx.beginPath(); ctx.moveTo(20 + 30 * i, 30); ctx.lineTo(20 + 30 * i, 100); ctx.lineWidth = 20; ctx.lineCap = lineCaps[i]; ctx.stroke(); }

ctx.beginPath(); ctx.moveTo(0, 30); ctx.lineTo(300, 30);

ctx.moveTo(0, 100); ctx.lineTo(300, 100)

ctx.strokeStyle = "red"; ctx.lineWidth = 1; ctx.stroke();



### 3. lineJoin = type

Set the style of the joint where lines connect within the same path.

There are 3 values: `round`, `bevel`, and `miter`:

-

`round`: The corner is drawn by filling an additional sector with the center at the end of the connected parts, and the radius of the arc is the width of the line.

-

`bevel`: An additional triangular area is filled at the end of the connected parts, with each part having its own separate rectangular corner.

-

`miter` (default): An additional diamond-shaped area is formed by extending the outer edges of the connected parts to intersect at a point.


function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d");

var lineJoin = ['round', 'bevel', 'miter'];
ctx.lineWidth = 20;

for (var i = 0; i < lineJoin.length; i++){
    ctx.lineJoin = lineJoin[i];
    ctx.beginPath();
    ctx.moveTo(50, 50 + i * 50);
    ctx.lineTo(100, 100 + i * 50);
    ctx.lineTo(150, 50 + i * 50);
    ctx.lineTo(200, 100 + i * 50);
    ctx.lineTo(250, 50 + i * 50);
    ctx.stroke();
}

} draw();



### 4. Dashed lines

Use the `setLineDash` method and the `lineDashOffset` property to specify the dashed line style. The `setLineDash` method accepts an array to specify the alternation of line segments and gaps; the `lineDashOffset` property sets the starting offset.

function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; var ctx = canvas.getContext("2d");

ctx.setLineDash([20, 5]);  // [solid line length, gap length]
ctx.lineDashOffset = -0;
ctx.strokeRect(50, 50, 210, 210);

} draw();


**Note**: getLineDash() returns an array containing the current dashed style, with a length that is a non-negative even number.

---

## Six, Drawing Text

### Two methods for drawing text

The canvas provides two methods for rendering text:

-

`fillText(text, x, y [, maxWidth])` Fills the specified text at the specified (x,y) position, with an optional maximum width for drawing.

-

`strokeText(text, x, y [, maxWidth])` Draws the text outline at the specified (x,y) position, with an optional maximum width for drawing.


var ctx; function draw(){ var canvas = document.getElementById('tutorial'); if (!canvas.getContext) return; ctx = canvas.getContext("2d"); ctx.font = "100px sans-serif" ctx.fillText("Heaven has feelings", 10, 100); ctx.strokeText("Heaven has feelings", 10, 200) } draw();



### Adding styles to text

-

`font = value` The style we currently use to draw text. This string uses the same syntax as the `CSS font` property. The default font is `10px sans-serif`.

-

`textAlign = value` Text alignment option. The possible values include: `start`, `end`, `left`, `right`, or `center`. The default value is `start`.

-

`textBaseline = value
This is a Chinese to English translation, please provide the English translation for this text. Do not provide any explanations or text apart from the translation.

English:

```javascript
ctx.restore(); // Restore the previous color state
ctx.fillRect(45, 45, 60, 60); // Draw a rectangle using the last configuration

ctx.restore(); // Load the default color configuration
ctx.fillRect(60, 60, 30, 30); // Draw a rectangle using the loaded configuration
}
draw();

Nine, Transformation

9.1 translate

translate(x, y)

Used to move the canvas origin to a specified location.

The translate method accepts two parameters. x is the horizontal offset, y is the vertical offset, as shown in the figure on the right.

It is a good habit to save the state before transforming. In most cases, calling the restore method is much simpler than manually restoring the original state. Also, if you are doing displacement in a loop without saving and restoring the canvas state, you may find that some things are missing in the end, because it is likely that it has gone beyond the range of the canvas.

Note: translate moves the coordinate origin of the canvas (coordinate transformation).

var ctx;
function draw(){
    var canvas = document.getElementById('tutorial1');
    if (!canvas.getContext) return;
    var ctx = canvas.getContext("2d");
    ctx.save(); // Save the state before the origin translation
    ctx.translate(100, 100);
    ctx.strokeRect(0, 0, 100, 100)
    ctx.restore(); // Restore to the initial state
    ctx.translate(220, 220);
    ctx.fillRect(0, 0, 100, 100)
}
draw();

9.2 rotate

rotate(angle)

Rotate the coordinate axis.

This method only accepts one parameter: the angle of rotation (angle), which is a clockwise value in radians.

The center of rotation is the coordinate origin.

var ctx;
function draw(){
  var canvas = document.getElementById('tutorial1');
  if (!canvas.getContext) return;
  var ctx = canvas.getContext("2d");

  ctx.fillStyle = "red";
  ctx.save();

  ctx.translate(100, 100);
  ctx.rotate(Math.PI / 180 * 45);
  ctx.fillStyle = "blue";
  ctx.fillRect(0, 0, 100, 100);
  ctx.restore();

  ctx.save();
  ctx.translate(0, 0);
  ctx.fillRect(0, 0, 50, 50)
  ctx.restore();
}
draw();

9.3 scale

scale(x, y)

We use it to increase or decrease the number of pixels of the shape in the canvas, to reduce or enlarge the shape, bitmap.

The scale method accepts two parameters. x,y are the scaling factors for the horizontal and vertical axes, respectively, and both must be positive values. A value less than 1.0 indicates reduction, a value greater than 1.0 indicates enlargement, and a value of 1.0 has no effect.

By default, 1 unit of canvas is 1 pixel. For example, if we set the scaling factor to 0.5, 1 unit becomes 0.5 pixels, and the resulting shape will be half of the original. Similarly, when set to 2.0, 1 unit corresponds to 2 pixels, and the result is that the shape is enlarged by 2 times.

9.4 transform (Transformation Matrix)

transform(a, b, c, d, e, f)

Ten, Composition

In all the previous examples, we always draw one shape on top of another. For many other situations, this is far from enough. For example, for composite shapes, there are restrictions on the drawing order. However, we can use the globalCompositeOperation property to change this situation.


// Draw the Earth image ctx.drawImage(earth, -12, -12);

// Draw the moon's orbit ctx.beginPath(); ctx.strokeStyle = "rgba(255,255,255,.3)"; ctx.arc(0, 0, 40, 0, 2 * Math.PI); ctx.stroke();

// Draw the moon ctx.rotate(2 * Math.PI / 6 * time.getSeconds() + 2 * Math.PI / 6000 * time.getMilliseconds()); ctx.translate(40, 0); ctx.drawImage(moon, -3.5, -3.5); ctx.restore();

requestAnimationFrame(draw); }



## Example 2: Simulate a Clock

init();

function init(){ let canvas = document.querySelector("#solar"); let ctx = canvas.getContext("2d"); draw(ctx); }

function draw(ctx){ requestAnimationFrame(function step(){ drawDial(ctx); // Draw the dial drawAllHands(ctx); // Draw hour, minute, and second hands requestAnimationFrame(step); }); } /* Draw hour, minute, and second hands */ function drawAllHands(ctx){ let time = new Date();

let s = time.getSeconds();
let m = time.getMinutes();
let h = time.getHours();

let pi = Math.PI;
let secondAngle = pi / 180 * 6 * s;  // Calculate the angle for the second hand
let minuteAngle = pi / 180 * 6 * m + secondAngle / 60;  // Calculate the angle for the minute hand
let hourAngle = pi / 180 * 30 * h + minuteAngle / 12;  // Calculate the angle for the hour hand

drawHand(hourAngle, 60, 6, "red", ctx);  // Draw the hour hand
drawHand(minuteAngle, 106, 4, "green", ctx);  // Draw the minute hand
drawHand(secondAngle, 129, 2, "blue", ctx);  // Draw the second hand

} /* Draw the hour, minute, or second hand

/* Draw the dial */ function drawDial(ctx){ let pi = Math.PI;

ctx.clearRect(0, 0, 300, 300); // Clear all content
ctx.save();

ctx.translate(150, 150); // Move the coordinate origin to the original center
ctx.beginPath();
ctx.arc(0, 0, 148, 0, 2 * pi); // Draw the circumference
ctx.stroke();
ctx.closePath();

for (let i = 0; i < 60; i++){// Draw the scale marks.
    ctx.save();
    ctx.rotate(-pi / 2 + i * pi / 30);  // Rotate the coordinate system. The x-axis of the coordinate system starts from the upward direction
    ctx.beginPath();
    ctx.moveTo(110, 0);
    ctx.lineTo(140, 0);
    ctx.lineWidth = i % 5 ? 2 : 4;
    ctx.strokeStyle = i % 5 ? "blue" : "red";
    ctx.stroke();
    ctx.closePath();
    ctx.restore();
}
ctx.restore();

}

```

>

Original Author: 做人要厚道2013

Original Link: https://blog.csdn.net/u012468376/article/details/73350998

**Click to Share Notes

Cancel

-

-

-

English:

❮ Go Channel Intro Android Tutorial Date Time 1 ❯