I use hover tooltips in my map. When an area is hovered, I show a tooltip with a small XY shift to the top left corner so that the pointer of the tooltip is not covered by the mouse cursor.
When I move mouse cursor to another area, near its border, like show in the image, the area is highlighted which is under the cursor, not under the square pointer as should be.
What are options to fix this issue? In the ideal way, I would like hover effect to be applied not to the mouse cursor coordinates, but to the coordinates of some other point that is known and changes while mouse is moving.
I once had a similar problem that I tried to solve with a different approach. I wanted to calculate the centroid of the polygon and always place the marker (in your case square pointer) on the calculated position once the user hovers over the polygon.
Main problem I had was that my polygons were concave and had holes in them (you will have the same problem if you are working with country borders) so I found a good algorithm (library) that I used to do this called Polylabel.
You can read more on this topic and how the guys from MapBox used it to solve their label positioning problems on this link.
Although this is not the answer to your question I found that this solution is fast and usable but only if the relation between the zoom level and polygon surface makes sense.
If I wanted to do something like you are suggesting I would first have a default point offset and if that offset goes outside the polygon I would find the nearest point in the polygon coordinates and attach it to that point.
To do these calculations you can use turf.js library. It has the function to return boolean value if the second geometry is completely contained by the first geometry and others that can help you to find the nearest point on the polygon border. I hope this helps!
Related
I am working on an image editor project, where you can rotate and crop an image.
The problem I'm currently facing is once I've rotated the image, I'd like to be able to drag the crop box anywhere inside the boundaries of the rotated image. So far I've been looking at the Liang-Barsky and Cohen-Sutherland line-clipping algorithms, and Separating Axis Theorem, but I'm struggling to see how I can implement these for my use case.
Can anyone point me in the right direction? Am I barking up the wrong tree?
Use the comment by Alain. To check insideness of the corners, it suffices to counter-rotate the image to make its edges axis-aligned. Then you have an easy point-in-axis-aligned-box problem.
(I don't mean that you really have to rotate the image, just the geometry.)
If the movement that the user tries to make is [dx,dy] then consider the line segments from the corners of the selection to those points translated by [dx,dy] (the yellow lines in the example below). These lines may intersect with the rotated image boundaries (green lines) at certain points (the red dots). If there are no intersections, then the movement is legal. If there are one or more intersections, these will tell you up to which point the movement was legal; the intersection point which is closest to its original position (checking either horizontal or vertical distance is enough to establish this) determines the maximum movement (the bottom right corner in the example). You can then limit the translation to this point.
Depending on which quadrant the direction of the movement is in (towards top right in the example) you can skip checking one of the corners (the bottom left corner in the example); the other corners will always bump into the boundaries first.
You can also skip checking two of the boundaries (bottom and left in the example), by comparing the direction of the movement with the rotation angle of the image.
So you need to check for intersections of 3 line segments with 2 line segments. For line segment intersection code, see e.g. this question.
If the user is dragging only one side, and extending the rectangle instead of moving it, then you only have to check the two corners that are moving.
I am using threejs (r73). I use a PerspectiveCamera. My goal is to implement mouse interaction. For that purpose I want to use
TrackballControls.js . But I want a slightly different behaviour.
I want to rotate around the point that the user picked on the screen
I want to zoom in direction of the mouse position
For the second point I already found a "solution" at stackoverflow. The zoom works, but when I change the target vector of the control, panning and rotating does not work any longer.
Can anyone provide such an modified implementation of TrackballControls or help me with that?
EDIT
With the applied "solution" panning still works but rotating doesn't.
The idea from https://stackoverflow.com/a/16817727/2657179 also does not work.
I am using Fabric.js to draw some element in a canvas.
I also used clipping section. So the user is only able to see the clipped section.
The issue is, some section is near to the top of the clipping area. So when the user selects that object, then they are not able to see the rotation point.
See this Image:
I have no idea how to changethe position of that rotation point.
Try to use
canvas.controlsAboveOverlay = true
Instead of moving the point. You should have controls visible outside clipping area if they are still on the canvas.
This is not really an answer for "change position of rotating point" is more fore "make the controls visible outside clipping area" but as of now changing the rotating point is possibile only modifing the library and with a lot of complexity.
I have realy specific question about Canvas handling mouse-events.
I'm working on a isometric game, I have a displayed map with all tiles, and I want know on which one the mouse are.
On a basic isometric map it's easy to transform the position on the screen (blue on the next image) on a map position (orange) with basic affine function (ax+b, with 'a' is width_tile/height_tile and b is the current position of the map view, red line on the image)..
But I have a complication, each tile of the game have a specific elevation (displayed by red arrow on second image). So i can't use a function for each line(y)/column(x) of the map.
On the same technique I'll try to calculate if mouse position are on EACH tile one by one for EACH mouse event (move, click, ..) but I'm afraid for the heavy code : if I have a 100x100 map and I shack the mouse, I'm sure all this test will ruin the client browser..
I realy don't know how can I do it better ?!
Someone have an idea, or a tips to optimize this check ?
Recently, I decided to delve into the world of HTML5 and the canvas and I have run into an issue that I cannot figure out how to solve.
I am using the zoom technique that was mentioned in this question, as I need to be able to zoom into a specific point.
However, the issue I have encountered is when you zoom into an area, and then perform a large mouse movement, and then zoom out. The entire viewpoint and objects become skewed. (Objects that were previously occupying the entire canvas, are now partially or sometimes not visible at all.)
I am assuming that the zoom in towards a point function is using the mouse position upon zooming out, which is causing these issues.
Here is a demo to get an idea of the issue: (again to reproduce, just zoom in move the mouse a reasonable distance and zoom out)
Not-Working Demo
This is working as designed. When you apply your context translation based on the mouse position it will zoom centered on that position.
To achieve the fixed zoom out behavior I think you want you need to set the mouseX and mouseY only on zoom in and then use the last mouseX/mouseY (or possibly the center of the canvas, or some point in between) for zoom out.
Updated JSFiddle