hoverOut() interferes with drag function when dragging too fast in Raphael - javascript

I have a shape that has hoverIn() and hoverOut() function and it can be dragged at the same time. My problem is when I drag too fast (not like really really fast), the mouse pointer may go outside of the shape boundary before the shape is actually moved. This cause hoverOut to be fired and it messes up with my dragging function. When I drag slow, this doesn't happened since the shape displacement is small and the mouse is always inside.
How can I handle the fact that if I'm dragging I don't want to deal with hoverOut. I tried the unHoverfunction(), it partially worked but now after dragging and leaving the shape the hoverOut function is not fired as it should be.

I've just created a flag, it seems like no built-in solution exist. Thanks for your time.

Related

mouse moves faster than tooltip

I have an angular directive wrapped around a D3 graph. I have created a tooltip and i handle the visibility in 'mouseover' and 'mouseout' of the parent element, i also handle the tooltip position in 'mousemove' so that it moves with the mouse.
The tooltip is absolute.
The issue is, when i move my mouse pointer fast enough, the mouseout event of the parent gets called , even though the mouse pointer is still within the specified area. I logged and found out , it is happening because sometimes the mouse pointer (when moving fast, the tooltip position hasn't updated so quick) hovers over the tooltip , which is absolutely positioned and not part of the parent.
This creates some difficulties as on mouseout of the parent element i am also changing the visibility of another element, so it gives a fluctuating/flicker kind of effect on fast mouse move.
I am not sure whether this is the expected behavior or if it is specific to D3 or angular.
Here is a fiddle:
http://jsfiddle.net/6bQA8/5/
initially the text and polylines are shown, they would hide when hovered over any of the pie slices.
on hover over any of the pie slices, you will get a tooltip, if you move your mouse, the tooltip also moves, if you move your mouse fast enough, check the console and you will see "tooltip hovered" ,also on the UI you would see the flickering text and polylines which should be visible on mouseout from the slices.
In ideal case, "tooltip hovered" should never be called as the tooltip always updates with the mouse and it is not below the pointer.
P.S: one way to solve the problem is to add pointer-events:none to the tooltip or to increase the offset of tooltip from the pointer, but i am more interested in knowing why this happens and if this is a limitation of the framework or the browser or something wrong in the code. Also, since i am re-using the same tooltip object later for clicking purpose, so at that time i would have to remove the pointer-events:none, and increasing the offset does not look really good in the UI. Also, both these methods are actually hacks and not probably the correct solution.
Since you are asking a solution apart from the pointer-events:none i have done it this way:
slices.on("mouseout", function(d) {
//return if the mouse out is triggered by the tooltip-menu
if(d3.select(d3.event.toElement).classed("tooltip_menu")){
return;//if the to element is tooltip_menu
}
working fiddle here
Javascript can not block mouse until it does all calculations and DOM manipulations, that's why, there is dealy in moving the tooltip.
In modern browsers operations happens at least with 4ms delay, as setTimeout/setInterval minimum delay is 4ms.

How to enable dragging off the control to scroll and extend the selection

I'm creating a custom scrolling control using HTML's Canvas that behaves a little like a spreadsheet grid. I have most standard cursor control behaviors set up, including using the mouse or arrow keys to extend the selection.
What I'd like to do next is allow the user to extend the selection by clicking and dragging off the canvas. I don't need help with the actual code, but I'd like to know if anyone has programmed something like this before, and if so, how did they approach it? Here are the ways I can think of:
Track the mouse's general direction while over the control, and on mouseLeave+mouseDown set up a timer to scroll that direction until mouseEnter+mouseDown
Determine the last location of the mouse before mouseLeave+mouseDown and use that to determine scroll direction
Start a slow scroll when mouse is within a few pixels of an edge (which edge determines direction) and then scroll faster on mouseLeave+mouseDown
Somehow involve window.mouseMove (instead of canvas.mouseMove) and track it that way (which seems really ugly to me)
Something else I'm missing that will seem really obvious in retrospect
I can handle the code, I just want to figure out the best conceptual approach to take. Ideally, I'd love to handle extending the selection diagonally (scrolling right and down simultaneously, or at least alternating between the two so it appears that way), but that's not a deal breaker.
You can use .setCapture to let your canvas continue to get mouse events even when the mouse is moved outside the canvas:
https://developer.mozilla.org/en-US/docs/Web/API/Element.setCapture

SVG Path Hit-Testing

I am having problems detecting mouseover events on SVG path elements. It seems that the smaller the strokeWidth for the path element, the less success I have in detecting the mouseover.
Also, I am using jquery-svg plugin to do the drawing.
Below is a fiddle of trying to detect using a jquery mouseover event on the path element.
Mouseover Fiddle
Below is a fiddle of trying to detect by attaching a mousemove listener to svg, then using document.getElementFromPoint.
getElementFromPoint Fiddle
Neither of these seem to work reliably, especially if the mouse is moving fast. Is it possible to make either of these more sensitivity to better detect the mouseover? Or perhaps a better way of doing this?
The way browsers work, you don't get mouseover events continuously, but you get one each time the operating system updates the cursor position. And if the mouse is moving fast, you will get a events a few pixels apart. The mouse doesn't slide over the document, it jumps. Here's a jsfiddle showing where each event occurs. There's nothing that you can do to get mouseover events for all the elements between two consecutive positions of the cursor.
You could do something different: remember the previous location of the mousemove event, compute the line between that point and the current mouse position, and compute all the intersections between this line and all the other shapes in the document. But that is going to be resource-intensive, since there's no API available for that, you'll have to compute intersections yourself. There is a library that can help you.

Attaching mouse events to a Raphael rect

I'm trying to draw rectangles with the mouse using the Raphael 2+ library (note: the answer to this question won't work with Raphael 2).
With rectangles (Paper.rect), the mousedown/mouseup events only trigger when the cursor is on the edge of the rectangle and not within it. Is there a way to attach these events so they trigger when the mouse cursor is within the rectangle?
Ultimately, I'm trying to draw marquees/frames with the mouse. Ideally, I'd like to attach mouse listeners to the paper, but this is no longer possible, so I'm creating a 'surface' rect on the paper and drawing my elements within it. Is this approach whack? Any ideas most welcome.
I've played around, and it seems that you have to fill your shape in order to have your events fired. See here : http://jsfiddle.net/bathz/KrpKs/
That just makes sens to me, It enables you to sharply define the perimeter of what you listen to. I guess you could fill the shape with a transparent color, but I'll leave it to you.

Handle mouse event on irregular shaped objects with event delegation

I need to handle mouse events on a page where there are multiple irregular-shaped objects (for example, houses) are stacked on top of each other. If I use the normal way of event delegation jQuery .on(), the event source reported will always be the top most object, even if user clicked on the transparent part of the object (or image).
Example: <img> tag that contains the red triangle will always be the event source even if I click at the X position.
I can detect that mouse click is not inside the triangle. What I need is a way to "forward" the event to the green triangle below.
EDIT: My current approach is to catch the events on a big div that wraps everything, then use jQuery selector and compare coordinates to find out which object is under the mouse, then check if the mouse is in transparent part or not. It works fine, but seems to be slow and consume a lot of memory, especially with mouse move events being fired continuously.
EDIT 2:
This image was extracted from Building a game engine with jQuery, and my approach was almost identical to that. And now, this is the question:
Are you drawing complex graphics using plain HTML elements? Not sure about your exact needs, but it might make more sense to use SVG or Canvas, where catching click events on shapes becomes much easier.

Categories

Resources