Since I started working, I have written about vue, react, regular rules, algorithms, small programs, etc., but I have never written about canvas, because I really don’t know how!
In 2018, I set a small goal for myself: learn canvas, and achieve the result of being able to use canvas to realize some animations that are not easy to achieve with CSS3.
This article is the first gain from learning canvas. The first demo that many people do when learning canvas is to implement a clock. Of course, I also implemented one, but instead of talking about this, I will talk about a more interesting and simpler one. stuff.
Hold down the mouse to draw the trajectory needOn a canvas, there is nothing on the canvas in the initial state. Now, I want to add some mouse events to the canvas and use the mouse to write on the canvas. The specific effect is to move the mouse to any point on the canvas, then hold down the mouse, move the mouse position, and you can start writing!
principleLet’s briefly analyze the idea. First, we need a canvas, then calculate the position of the mouse on the canvas, bind the onmousedown event and onmousemove event to the mouse, and draw the path during the movement. When the mouse is released, the drawing ends.
Although this idea is very simple, there are some parts that require some tricks to implement.
1. An html file is required, containing canvas elements.
This is a canvas with a width of 800 and a height of 400. Why didn't you write px? Oh, I don’t understand it yet, it’s recommended by the canvas document.
<!doctype html><html class=no-js lang=zh> <head> <meta charset=utf-8> <meta http-equiv=x-ua-compatible content=ie=edge> <title>canvas learning< /title> <meta name=description content=> <meta name=viewport content=width=device-width, initial-scale=1> <link rel=manifest href=site.webmanifest> <link rel=apple-touch-icon href=icon.png> <link rel=stylesheet href=css/main.css> </head> <body> <canvas id=theCanvas width=800 height =400></canvas> <script src=js/main.js></script> </body></html>
2. Determine whether the current environment supports canvas.
In main.js, we write a self-executing function. The following is the code snippet for compatibility judgment. The main body of the code will be the core of the implementation requirements.
(function() { let theCanvas = document.querySelector('#theCanvas') if (!theCanvas || !theCanvas.getContext) { //Incompatible with canvas return false } else { //Code body}})()
3. Get the 2d object.
let context = theCanvas.getContext('2d')
4. Get the coordinates of the current mouse relative to the canvas.
Why do we need to obtain this coordinate? Because the mouse defaults to obtaining the relative coordinates of the current window, and the canvas can be located anywhere on the page, calculations are required to obtain the real mouse coordinates.
Obtaining the real coordinates of the mouse relative to the canvas is encapsulated into a function. If you feel abstract, you can draw a picture on a scratch paper to understand why this operation is required.
Typically, this would be x - rect.left and y - rect.top. But why is it actually x - rect.left * (canvas.width/rect.width)?
canvas.width/rect.width means to determine the scaling behavior in canvas and find the scaling multiple.
const windowToCanvas = (canvas, x, y) => { //Get some attributes of the canvas element distance window, explained on MDN let rect = canvas.getBoundingClientRect() //The x and y parameters are passed in respectively from the mouse distance window coordinates, and then subtract the distance between the canvas and the left and top of the window. return { x: x - rect.left * (canvas.width/rect.width), y: y - rect.top * (canvas.height/rect.height) }}
5. With the tool function in step 4, we can add mouse events to the canvas!
First bind the onmousedown event to the mouse and use moveTo to draw the starting point of the coordinates.
theCanvas.onmousedown = function(e) { //Get the coordinates of the point where the mouse is pressed relative to the canvas. let ele = windowToCanvas(theCanvas, e.clientX, e.clientY) //Destructuring assignment of es6 let { x, y } = ele //The starting point of drawing. context.moveTo(x, y)}
6. When moving the mouse, there is no mouse long press event, how to monitor it?
The little trick used here is to execute an onmousemove (mouse movement) event inside onmousedown, so that the mouse can be monitored and moved.
theCanvas.onmousedown = function(e) { //Get the coordinates of the point where the mouse is pressed relative to the canvas. let ele = windowToCanvas(theCanvas, e.clientX, e.clientY) //Destructuring assignment of es6 let { x, y } = ele //The starting point of drawing. context.moveTo(x, y) //Mouse move event theCanvas.onmousemove = (e) => { //Get the new coordinate position when moving, use lineTo to record the current coordinates, and then stroke to draw the previous point to the current point Path let ele = windowToCanvas(theCanvas, e.clientX, e.clientY) let { x, y } = ele context.lineTo(x, y) context.stroke() }}
7. When the mouse is released, the path will no longer be drawn.
Is there any way to prevent the two events monitored above in the onmouseup event? There are many methods. Setting onmousedown and onmousemove to null is one. I used switches here. isAllowDrawLine is set to a bool value to control whether the function is executed. For the specific code, please see the complete source code below.
Source codeIt is divided into 3 files, index.html, main.js, and utils.js. The syntax of es6 is used here. I used parcle to configure the development environment, so there will be no errors. If you copy the code directly, when running If an error occurs and the browser cannot be upgraded, you can change the es6 syntax to es5.
1.index.html
It has been shown above and will not be repeated again.
2.main.js
import { windowToCanvas } from './utils'(function() { let theCanvas = document.querySelector('#theCanvas') if (!theCanvas || !theCanvas.getContext) { return false } else { let context = theCanvas.getContext ('2d') let isAllowDrawLine = false theCanvas.onmousedown = function(e) { isAllowDrawLine = true let ele = windowToCanvas(theCanvas, e.clientX, e.clientY) let { x, y } = ele context.moveTo(x, y) theCanvas.onmousemove = (e) => { if (isAllowDrawLine) { let ele = windowToCanvas(theCanvas , e.clientX, e.clientY) let { x, y } = ele context.lineTo(x, y) context.stroke() } } } theCanvas.onmouseup = function() { isAllowDrawLine = false } }})()
3.utils.js
/** Get the coordinates of the mouse on the canvas* */const windowToCanvas = (canvas, x, y) => { let rect = canvas.getBoundingClientRect() return { x: x - rect.left * (canvas.width/rect .width), y: y - rect.top * (canvas.height/rect.height) }}export { windowToCanvas}Summarize
There is a misunderstanding here. I use the canvas object to bind the event theCanvas.onmouseup. In fact, canvas cannot bind events. What is really bound is document and window. But since the browser will automatically judge it for you and hand over event processing, there is no need to worry at all.
The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.