jquery-powertip icon indicating copy to clipboard operation
jquery-powertip copied to clipboard

isMouseOver Calculated Incorrectly for path Elements, Leading to Closing Powertip

Open speedplane opened this issue 9 years ago • 6 comments

Powertip's isMouseOver function does not properly calculate the height of SVG elements, which causes it to determine that the mouse is not over an object when it really is.

The reason for this is that getBoundingClientRect does not include the height of stroke-width in its calculation. I fixed this with the following monkey-hack:

    function isMouseOver(element) {
        // use getBoundingClientRect() because jQuery's width() and height()
        // methods do not work with SVG elements
        // compute width/height because those properties do not exist on the object
        // returned by getBoundingClientRect() in older versions of IE
        var elementPosition = element.offset(),
            elementBox = element[0].getBoundingClientRect(),
            elementWidth = elementBox.right - elementBox.left,
            elementHeight = elementBox.bottom - elementBox.top;

        // Add stroke width to paths
        var (element[0].tagName == 'path') {
            var stroke = window.getComputedStyle(element[0])
                .getPropertyValue("stroke-width");
            if (stroke && stroke.length && parseFloat(stroke) > 0) {
                    elementHeight += parseFloat(stroke)
            }
        }

        return session.currentX >= elementPosition.left &&
            session.currentX <= elementPosition.left + elementWidth &&
            session.currentY >= elementPosition.top &&
            session.currentY <= elementPosition.top + elementHeight;
    }

speedplane avatar Apr 06 '15 08:04 speedplane

I created a jsfiddle where you can see this bug: https://jsfiddle.net/ojkkj8Le/ Try scrolling over the blue path. Notice how the powertip appears and then disappears.

speedplane avatar Apr 06 '15 08:04 speedplane

The JSFiddle example you supplied is using an outdated version of the library, version 1.1.0. SVG support was not added until version 1.2.0.

Here is a fork of your fiddle using version 1.2.0: https://jsfiddle.net/stevenbenner/Lv6t1bvq/

It no longer shows the unexpected closing behavior. However, it does seem to put the tooltip in an unexpected place.

stevenbenner avatar Apr 06 '15 20:04 stevenbenner

It's still disappearing for me. Try moving your mouse below the middle of the svg (see updated fiddle): https://jsfiddle.net/e6217g42/

speedplane avatar Apr 06 '15 21:04 speedplane

Actually, try this jsfiddle: https://jsfiddle.net/e6217g42/2/

speedplane avatar Apr 06 '15 21:04 speedplane

What browser are you using?

I was able to reproduce the issue in Chrome. I cannot repro in Firefox or IE.

It seems that getBoundingClientRect() ignores the stroke width in Chrome (probably WebKit heritage, which would affect Safari and Opera as well). And getBBox() doesn't factor in the stroke on any browser.

This may be a very complicated fix because I have to handle rotation. I'll investigate.

stevenbenner avatar Apr 06 '15 21:04 stevenbenner

Yes Chrome. It does seem complicated, my Monkey hack only works for non-rotated paths, and only does height, not width. You may want to consider turning off the desync check for path elements.

speedplane avatar Apr 06 '15 21:04 speedplane