Demand
On a canvas canvas, the initial state canvas has nothing, and now I want to add a little mouse event to the canvas and write on the canvas with the mouse. The specific effect is to move the mouse to any point on the canvas, and then hold the mouse, move the position of the mouse, you can start to write!
This article as a learning canvas first harvest, many people learn canvas to do the first demo is to achieve a "clock", of course, I also achieved a, but not this, but to talk about a more interesting, more simple thing.
Mouse down Draw track
Principle
First of all, a simple analysis of the idea, we need a canvas canvas, and then calculate the mouse position on the canvas, to the mouse binding onmousedown events and onmousemove events, in the process of drawing out the path, release the mouse, draw the end.
Although this idea is very simple, there are some places where small tricks are needed to achieve this.
1. An HTML file is required, including the canvas element.
This is a canvas with a width of 800 and a height of 400. Why didn't you write the px? Oh, not at the moment, the canvas document recommends.
<!doctype html>
2, determine whether the current environment supports canvas.
In Main.js, we write a self-executing function, the following is a code fragment of the compatibility judgment, and the "Code body" will be the core of the implementation requirements.
(function () {let Thecanvas = Document.queryselector (' #theCanvas ') if (!thecanvas | |!thecanvas.getcontext) { c2/>//incompatible with canvas return False } else { //code Body }}) ()
3. Get 2d objects.
Let context = Thecanvas.getcontext (' 2d ')
4. Gets the coordinates of the current mouse relative to the canvas.
Why do you want to get this coordinate? Because the mouse default is to get the relative coordinates of the current window, and the canvas can be anywhere on the page, you need to calculate to get the real mouse coordinates.
Encapsulates the mouse's actual coordinates with respect to the canvas as a function, and if you feel abstract, you can draw on the draft paper to understand why.
Typically, it can be x-rect.left and y-rect.top. But why is it actually x-rect.left * (canvas.width/rect.width)?
Canvas.width/rect.width indicates the scaling behavior that exists in the canvas, and the multiplier of the scale is calculated.
CONST Windowtocanvas = (canvas, x, y) = = { //Gets the canvas element from some properties of the window, the MDN has an explanation of let rect = The Canvas.getboundingclientrect () //x and Y parameters pass in the coordinates of the mouse distance window respectively, and then subtract the distance from the left and top of the canvas from the window. return { x:x-rect.left * (canvas.width/rect.width), y:y-rect.top * (Canvas.height/rect.height) }}
5, with the 4th step of the tool function, we can add mouse events to the canvas!
First, bind the mouse to press the onmousedown event and draw the coordinates starting point with moveto.
Thecanvas.onmousedown = function (e) { //Gets the coordinates of the mouse-pressed point relative to the canvas. Let ele = Windowtocanvas (Thecanvas, E.clientx, E.clienty) //es6 The deconstruction assignment let {x, y} = ele //Draw starting point. Context.moveto (x, y)}
6, when moving the mouse, no mouse long press events, and how to monitor it?
The trick here is to perform a onmousemove (mouse movement) event inside the onmousedown so that you can listen and hold the mouse and move.
Thecanvas.onmousedown = function (e) { //Gets the coordinates of the mouse-pressed point relative to the canvas. Let ele = Windowtocanvas (Thecanvas, E.clientx, E.clienty) //es6 The deconstruction assignment let {x, y} = ele //Draw starting point. Context.moveto (x, y) //Mouse Move event thecanvas.onmousemove = (e) + = { //move to get a new coordinate position, record the current coordinates with LineTo, Then the stroke draws the path of the previous point to the current point 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 is no longer drawn.
Is there any way to prevent the 2 events in the OnMouseUp event from being monitored? There are many methods, and setting onmousedown and onmousemove to null is a kind of, I use "switch" here. Isallowdrawline set to bool value, to control whether the function is executed, the specific code can see the complete source below.
Source
Divided into 3 files, index.html, Main.js, Utils.js, here to use the ES6 syntax, I am using parcle configuration of the development environment, so there will be no error, if you directly copy the code, run errors, in the case can not upgrade the browser, it is possible to change the ES6 syntax to ES5.
1, index.html
The above has been shown, no repetition.
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.CLI Enty) Let {x, y} = ele context.lineto (x, y) Context.stroke ()}} } Thecanvas.onmouseup = function () { Isallowdrawline = False }} ) ()
3, Utils.js
/** gets the coordinates of the mouse on the canvas * */const Windowtocanvas = (canvas, x, y) + = {Let Rect = CA Nvas.getboundingclientrect () return {x:x-Rect.left * (canvas.width/rect.width), Y:y-Rect.top * (ca Nvas.height/rect.height)}}export {Windowtocanvas}