preface

A few days ago, I got a job and needed to make a map of the parking lot. The first thing I thought of was to use Canvas to draw. Since I have only used Canvas in a superficial way in the early stage, but never used it formally in the project, this time I also touched the document and crossed the river πŸ˜‚.

How to draw

A Canvas is an HTML tag that requires a script to draw a graph.

easy to use

<canvas id="canvas"></canvas>

To add labels directly to the page, you must use scripts to draw graphics

var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); Canvas. Width = 500; canvas.height = 500; ctx.beginPath(); // start ctx.rect(10, 10, 100, 100); // draw a rectangle ctx.fillStyle = '#eee'; // Fill the color ctx.fill(); // Path padding

You can see that a simple rectangle will appear on the canvas



Among themgetContextIs to get the Canvas object; It takes two parameters:

  • contextTypeContext types (2D, WebGL, WebGL2)
  • contextAttributesContext attribute; For details please refer toMDN

The default height of the canvas is 300 Γ— 150. There is one important thing to note about the height setting here: if we use CSS to set the height, the canvas will be scaled at a scale of 300 Γ— 150. If you set the height to 500 Γ— 500, it may be distorted. So it’s better to use JavaScript or set the high width directly on the tag.

Draw step

From the above series of usage cases, we can summarize the general method of drawing the path

Create a canvas

Use the ID to get the canvas object

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

Start drawing paths

BeginPath is used to start drawing

ctx.beginPath();

Draw the path

Here we can use the various methods of drawing paths provided by Canvas; Some common rendering methods

methods describe
arc() Create a circular arc
rect() Create a rectangle
fillRect() Draws a rectangular path area
strokeRect() Draws a rectangular path stroke
arcTo() Creates an arc/curve between two tangents
moveTo() Moves the path to the specified point in the canvas without creating a line
lineTo() Add a new point, and then create lines in the canvas from that point to the last specified point
clip() Cut an area of any shape and size from the original canvas
quadraticCurveTo() Create quadratic Bezier curves
bezierCurveTo() Create a cubic Bezier curve

Fill or Stroke

After drawing the path, you can choose to close the path or fill or stroke the path directly. These are some common methods

ctx.fillStyle = '#eee'; // Fill the color ctx.fill(); // Path fills ctx. strokStyle = 'red'; // Path stroke color ctx.stroke(); // Path Stroke

Each drawing pattern can be divided into four basic steps. What we need to understand is that every time the coordinate points are drawn, as long as the coordinate points are confirmed, there is no error in the drawn graph.

The canvas operation

When the drawing of the parking lot is completed, it is necessary to click the parking space to display the use of parking space; Since clicking Canvas can only monitor the clicked coordinate point, it is necessary to judge whether the user clicks the position within the parking space. Now we know the coordinate of the starting point of the parking space and the width and height of the parking space, so the judgment condition is

PolylinePoints function checkpointInPolyline (point, point, point, point) PolylinePoints) {if (point.x >= polylinePoints. X &&x < point + width &&y < point + height) {if (point.x >= polylinePoints point.x <= polylinePoints.x + polylinePoints.w && point.y >= polylinePoints.y && point.y <= polylinePoints.y + polylinePoints.h ) { return true; } else { return false; }}

We all know that the canvas is drawn at the origin of the upper left corner of the page(0, 0)Start drawing, but since the parking lot is a vertically centered layout, when we click on the origin of the canvas we get the coordinates:



You can see that we’re not getting close(0, 0)This is due to the mouse takingdocumnetThe upper left corner is the origin to obtain coordinates; So if you click on a certain spot in the parking space, you need to click on a certain spot(x, y)Make the conversion.

I’m going to use it heregetBoundingclientRectThis function is used to get the position of the left, top, right, and bottom of an element on the page relative to the browser window. utilisedleft,topValue conversion

canvas.addEventListener('click', function(e) {
  console.log(convertPoint(e.x, e.y))
})

function convertPoint(x, y) {
  var _info = canvas.getBoundingClientRect()
  return {
    x: x - _info.left,
    y: y - _info.top
  }
}

And then you can see that the coordinates are close(0, 0)Canvas origin.



The font

To draw a font on Canvas, the key is to use fillText(text, x, y [, maxWidth]) :

  • textIs the text
  • x, yIs the starting point of the plot
  • maxWidthThe maximum width that fills the text

A full font drawing is also simple

ctx.fillStyle = '#333';
ctx.font = '18px SimSun, Songti SC';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('imondo.cn', 200, 200);



But when we want to use a custom font, we use a regular one@font-faceSetting discovery is useless, because the browser is usually lazy to load the font, in the process of drawing, the font has not been loaded successfully; A new API is recommended herenew FontFace, can listen for font loading, and isPormise

  const myFont = new FontFace('myFont', 'url(./webfont.ttf)');
  var _this = this;
  myFont
    .load()
    .then((font) => {
      document.fonts.add(font);
    })
    .then(function () {
      ctx.fillStyle = color;
      ctx.font = fontSize + ' myFont';
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText(text, x, y);
    });

Compatibility is still OK, of course, don’t consider IE (IE: feel offended to πŸ˜‚)

Canvas Rotation Scale

Rotate and scale are used for Canvas rotation and scale respectively. The most important thing to note is that they are all rotated or scaled based on the default center point (0, 0), so we need to translate to change the center point before the operation. When we need to rotate the text by 90Β°, we need to change the center point first and then rotate it. After the rotation, we need to restore the center point again, otherwise the next drawing by beginPath will be based on the center point after translate

ctx.beginPath()
ctx.translate(200, 200);
ctx.rotate( 90 * Math.PI / 180)
ctx.translate(-200, -200);
ctx.fillStyle = '#333';
ctx.font = '18px SimSun, Songti SC';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText('imondo.cn', 200, 200);



Same thing with scaling

ctx.translate(200, 200); CTX. Scale (1.5, 1.5); ctx.translate(-200, -200);



It’s just that you need to draw the starting coordinatestranslateCoordinates.

Blur the mobile end

When the entire parking lot was painted, it looked good; But when it is opened on the phone, it is so blurry that people have several hundred degrees of myopia; Search the whole network, or mobile terminal device pixel ratio problem. The solution is to detect the pixel ratio of the device and draw the canvas element with the corresponding multiple ratio

function createHDCanvas(w = 300, h = 150) { var ratio = window.devicePixelRatio || 1; var canvas = document.getElementById('canvas'); canvas.width = w * ratio; // canvas. Height = h * ratio; Canvas. Style. width = '${w}px'; Canvas. Style. Height = '${h}px'; Canvas. GetContext (' 2D '). SetTransform (ratio, 0, 0, ratio, 0, 0, 0); return canvas; }

conclusion

It has taken more than half a day to draw the whole painting. I am not familiar with Canvas, but I have a clearer understanding of the whole drawing process after the drawing is finished. Some of the later business technology or have a certain reserve 😊.

Finally attached:

  • Parking lot effect
  • Source code: address

Reference:

  • There are three ways to listen for click events on Canvas elements
  • Canvas element selection
  • Canvas shows blurring problem​

Welcome to 【 front-end learning what 】 to communicate together