Preface
I have received a job these days and need to make a parking lot diagram. The first thing that comes to my mind is to use Canvas to draw. Since Canvas was only used briefly in the early stage, and not officially used in the project, this time I also touched the document cross the river 😂.
How to draw
Canvas is a canvas, an Html tag that requires a script to draw graphics. <canvas>
simple to use
<canvas id="canvas"></canvas>
Add tags directly on 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(); // 开始路径
ctx.rect(10, 10, 100, 100); // 绘制矩形
ctx.fillStyle = '#eee'; // 填充颜色
ctx.fill(); // 路径填充
You can see that a simple rectangle will appear in the canvas
where getContext
is to get the Canvas object; it has two parameters:
contextType
context type (2d, webgl, webgl2)contextAttributes
context attributes; for details, please refer to MDN
The canvas has a default height of 300 × 150
. There is one point to note about the height setting here: if we use css
to set the height, the canvas will be scaled according to the ratio of 300 × 150, if you set 500 × 500, it may be deformed. So we'd better use Javascript
or set the high width directly on the label.
Drawing steps
From the above series of use cases, we can summarize the approximate method of drawing the path
Create the canvas
Use ID
to get the canvas object
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
Start drawing the path
Use beginPath
start drawing
ctx.beginPath();
Draw path
Here we can use the various methods of drawing paths provided by Canvas; some common drawing methods
Method | Description |
---|---|
arc() | Create arc |
rect() | Create rectangle |
fillRect() | Draw a rectangular path area |
strokeRect() | Draw a rectangular path stroke |
arcTo() | Create an arc/curve between two tangents |
moveTo() | Move the path to the specified point in the canvas without creating a line |
lineTo() | Add a new point, and then create a line from that point to the last specified point in the canvas |
clip() | Cut an area of any shape and size from the original canvas |
quadraticCurveTo() | Create a quadratic Bézier curve |
bezierCurveTo() | Create a cubic Bézier curve |
Fill or stroke
After drawing the path, you can choose to close the path closePath
or directly fill or stroke the path. These are some conventional methods
ctx.fillStyle = '#eee'; // 填充颜色
ctx.fill(); // 路径填充
ctx.strokeStyle = 'red'; // 路径描边颜色
ctx.stroke(); // 路径描边
Each graphic pattern drawn can be divided into these basic 4 steps. What we need to understand is actually the coordinate points drawn each time. As long as the coordinate points are confirmed, the drawn graph still has no errors.
Canvas operation
When the parking lot is drawn, it is necessary to click the parking space to display the parking space usage; since clicking on Canvas can only monitor the clicked coordinate point, it is necessary to determine whether the user clicked position is in the parking space, and now we know the starting point coordinates and the parking space width of the parking space High, so the judgment condition is
// 用户点击坐标 point
// 车位绘制信息 polylinePoints
function checkPointInPolyline(point, polylinePoints) {
// 当 x > 车位起始点 && x < 起始点 + 车位宽度 && y > 起始点 && y < 起始点 + 车位高度
if (
point.x >= polylinePoints.x &&
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 from the origin (0, 0)
upper left corner of the page, but because the parking lot is a vertically centered layout, when we click on the origin of the canvas, the coordinates
we can see that we get and It is not close to (0, 0)
. This is because the mouse documnet
the upper left corner of 060a7061fdf689 as the origin to obtain the coordinates; therefore, if you click a point in the parking space, you need to convert the (x, y)
Here you need to use getBoundingclientRect
, which is used to obtain the position of the left, top, right and bottom of an element in the page relative to the browser window; use the obtained left
, top
values to convert
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
}
}
As you can see next, the coordinate point is close to the origin of the (0, 0)
Font
To draw fonts in Canvas, the key is to use the fillText(text, x, y [, maxWidth])
function:
text
is the textx, y
is the starting point of drawingmaxWidth
The maximum width occupied by the filled text
A complete font drawing is also very 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, it is @font-face
use the conventional 060a7061fdf7f2 setting, because the browser loads fonts generally lazily. During the drawing process, the font has not been loaded successfully; here is a new one. API new FontFace
, you can monitor the font loading, and it is a Pormise
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);
});
IE
, of course, don’t consider 060a7061fdf82a (IE: I feel offended 😂)
Canvas rotation zoom
Canvas rotation and scaling use rotate
and scale
respectively. The most important thing to note is that they are all based on the default center point (0, 0)
to rotate or zoom, so before proceeding, we need to use translate
to change the center point.
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, otherwise the next time beginPath
drawn, it will be drawn 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 is true for scaling operations
ctx.translate(200, 200);
ctx.scale(1.5, 1.5);
ctx.translate(-200, -200);
In fact, the coordinates at the beginning of drawing are the coordinates of translate
.
Mobile obfuscation
When the entire parking lot is drawn, it looks pretty good; but when it is opened on a mobile phone, it is blurred and makes people myopia. Checking the entire network, it is still a problem of the pixel ratio of mobile devices. The solution is to detect the pixel ratio of the device and draw the canvas element corresponding to the 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);
return canvas;
}
to sum up
It has been almost half a day since the whole drawing, mainly because I Canvas
not familiar with 060a7061fdf969, but after the drawing is completed, I have a clearer understanding of the whole drawing process; I still have a certain reserve of some business technologies in the later period.
Finally, attach:
Reference:
- Three ways to monitor click events of Canvas internal elements
- Talk about the elements of the canvas Select
- Canvas display blur problem
Welcome to pay attention to [What the front-end learns] to communicate together
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。