In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces the relevant knowledge of "how to deal with HTML5 Canvas events". In the operation of actual cases, many people will encounter such a dilemma. Then let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
DOM is a very important part of the Web front-end domain, using DOM not only when dealing with HTML elements, but also in graphical programming. For example, SVG drawings, all kinds of graphics are inserted into the page in the form of DOM nodes, which means that you can use the DOM method to manipulate the graphics. For example, if you have an element, you can directly add the click event $('# p1'). Click (function () {…) with jquery. However, this DOM processing method is no longer applicable in HTML5's Canvas. Canvas uses a different set of mechanisms. No matter how many graphics are drawn on Canvas, Canvas is a whole. The graphics themselves are actually part of Canvas and cannot be obtained separately, so it is impossible to add JavaScript events to a figure directly.
Limitations of Canvas
In Canvas, all graphics are drawn on the frame, the drawing method will not output the drawn graphic elements as a return value, and js can not get the graphic elements that have been drawn. For example:
The code is as follows:
Cvs = document.getElementById ('mycanvas')
Ctx = canvas.getContext ('2d')
TheRect = ctx.rect (10,10,100,100)
Ctx.stroke ()
Console.log (theRect); / / undefined
This code draws a rectangle in the canvas tag, and you can first see that the rect method for drawing the graph does not return a value. If you open the developer tool of the browser, you can also see that there is nothing added inside the canvas tag, and the canvas elements obtained in js and the current context do not have any content that represents the new graphics.
Therefore, the dom method commonly used in the front end is not applicable in canvas. For example, if you click on the rectangle in the Canvas above, you will actually click on the entire Canvas element.
Bind events to Canvas elements
Since events can only reach the Canvas element level, if you want to go further and identify which graph the click occurred on within the Canvas, you need to add code to process it. The basic idea is to bind an event to the Canvas element, and when the event occurs, check the location of the event object, and then check which graphics override that location. For example, a rectangle is drawn in the above example, which covers the range of x-axis 10-110 and y-axis 10-110. As long as the mouse click in this range, it can be regarded as clicking on the rectangle, and you can manually trigger the click event that the rectangle needs to deal with. The idea is actually relatively simple, but it is still a little complicated to implement. Not only do you need to consider the efficiency of this judgment process, but there are places where you need to redetermine the event type and set up to redefine a capture and bubbling mechanism within the Canvas.
The first thing to do is to bind the event to the Canvas element. For example, if you want to bind a click event to a graph within Canvas, you need to proxy the event through the Canvas element:
The code is as follows:
Cvs = document.getElementById ('mycanvas')
Cvs.addEventListener ('click', function (e) {
/ /...
}, false)
Next, you need to determine the location of the event object, and the layerX and layerY properties of the event object e represent the coordinates in the Canvas internal coordinate system. However, Opera does not support this attribute, and Safari is going to remove it, so you need to do some compatible writing:
The code is as follows:
Function getEventPosition (ev) {
Var x, y
If (ev.layerX | | ev.layerX = = 0) {
X = ev.layerX
Y = ev.layerY
} else if (ev.offsetX | | ev.offsetX = = 0) {/ / Opera
X = ev.offsetX
Y = ev.offsetY
}
Return {x: x, y: y}
}
/ Note: to use the above function, you need to set the position of the Canvas element to absolute.
Now that you have the coordinate location of the event object, it's time to determine which of the graphics in Canvas overrides that coordinate.
IsPointInPath method
The isPointInPath method of Canvas can determine whether the drawing in the current context overrides certain coordinates, such as:
The code is as follows:
Cvs = document.getElementById ('mycanvas')
Ctx = canvas.getContext ('2d')
Ctx.rect (10,10,100,100)
Ctx.stroke ()
Ctx.isPointInPath (50,50); / / true
Ctx.isPointInPath (5,5); / / false
Next, add an event judgment to determine whether a click event occurs on a rectangle:
The code is as follows:
Cvs.addEventListener ('click', function (e) {
P = getEventPosition (e)
If (ctx.isPointInPath (p. X, p. Y)) {
/ / clicked the rectangle
}
}, false)
These are the basic methods for handling Canvas events, but the above code has limitations. Because the isPointInPath method only determines the path in the current context, when multiple graphs have been drawn in Canvas, events can only be judged in the context of the last graph, such as:
The code is as follows:
Cvs = document.getElementById ('mycanvas')
Ctx = canvas.getContext ('2d')
Ctx.beginPath ()
Ctx.rect (10,10,100,100)
Ctx.stroke ()
Ctx.isPointInPath (20,20); / / true
Ctx.beginPath ()
Ctx.rect (110,110,100,100)
Ctx.stroke ()
Ctx.isPointInPath (150150); / / true
Ctx.isPointInPath (20,20); / / false
As you can see from the above code, the isPointInPath method can only recognize the graphical path in the current context, while the previously drawn path cannot be traced back. The solution to this problem is: when the click event occurs, redraw all the graphics, each drawing on the use of isPointInPath method to determine whether the event coordinates are within the coverage of the graph.
Cycle redrawing and event bubbling
In order to achieve circular redrawing, the basic parameters of the graph should be saved in advance:
The code is as follows:
Arr = [
{x:10, y:10, width:100, height:100}
{x:110, y:110, width:100, height:100}
]
Cvs = document.getElementById ('mycanvas')
Ctx = canvas.getContext ('2d')
Draw ()
Function draw () {
Ctx.clearRech (0,0, cvs.width, cvs.height)
Arr.forEach (function (v) {
Ctx.beginPath ()
Ctx.rect (v.x, v.y, v.width, v.height)
Ctx.stroke ()
});
}
The above code saves the basic parameters of the two rectangles in advance, and each time the draw method is called, these basic parameters are called in a loop to draw the two rectangles. The clearRect method is also used here to empty the canvas when redrawing. The next thing to do is to add event proxies and use the isPointInPath method for each context when redrawing:
The code is as follows:
Cvs.addEventListener ('click', function (e) {
P = getEventPosition (e)
Draw (p)
}, false)
When an event occurs, the coordinates of the event object are passed to the draw method for processing. Here are some minor changes to the draw method:
The code is as follows:
Function draw (p) {
Var who = []
Ctx.clearRech (0,0, cvs.width, cvs.height)
Arr.forEach (function (v, I) {
Ctx.beginPath ()
Ctx.rect (v.x, v.y, v.width, v.height)
Ctx.stroke ()
If (p & & ctx.isPointInPath (p.x, p.y)) {
/ / if event coordinates are passed in, use isPointInPath to judge
/ / if the current environment overrides the coordinates, put the index value of the current environment in the array
Who.push (I)
}
});
/ / according to the index value in the array, you can find the corresponding element in the arr array.
Return who
}
In the above code, the draw method performs a redraw when the click event occurs, and checks whether each graph overrides the event coordinates during the redrawing process. If it is judged to be true, it is regarded as clicking on the graph, and the index value of the graph is put into the array. Finally, the array is used as the return value of the draw method. Under this processing mechanism, if there are N graphics in the Canvas, some of them overlap, and the click event happens to occur in this overlapping area, then there will be N members in the return array of the draw method. At this time, it is a bit like the event bubbling situation, the last member of the array is at the top of the Canvas, and the first member is at the lowest level, we can think of the top member as e.target, while the other members are the nodes passed during the bubbling process. Of course, this is only the simplest way to deal with it, and if you really want to simulate DOM processing, you have to set up a parent-child relationship for the graph.
This is the end of "how to deal with HTML5 Canvas events". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.