Search code examples
jquerycsssafarimousehover

Safari mouse move left position (x coordinate) not correct


Using a custom cursor in the Butterfly Builder app on this page, when applying the colors via the color palette section, however, Safari is not lining up the cursor where the mouse is moving over the .canvas-container Have tried both of these in order to line this up, but it never works:

var pBucketHTML = $('<div id="pBrush"><span class="color"></span></div>');
pBucketHTML.css('top', ((e.offsetY + $(this).offset().top) - (pBucketHTML.height() / 2)));
pBucketHTML.css('left', ((e.offsetX + $(this).offset().left) - (pBucketHTML.width() * 2)));

AND

var pBucketHTML = $('<div id="pBrush"><span class="color"></span></div>');
pBucketHTML.css('top', e.pageY - (pBucketHTML.height() / 2));
pBucketHTML.css('left', e.pageX - (pBucketHTML.width() * 2));

LESS I'm using for this:

#pBrush {
    width: 24px;
    height: 34px;
    background: transparent url('../images/paintBrush.png') left bottom no-repeat;
    position: fixed;

    .color {
        position: absolute;
        width: 12px;
        height: 12px;
        border: 1px solid #FFFFFF;
        display: inline-block;
        top: 0;
        right: 0;
        left: 0;
        margin: 0 auto;
    }
}

This is loading up the mouse cursor perfectly fine on Chrome and all other browsers, but Safari is not loading it up with the correct X coordinate... not sure why? Looks like the Y coordinate is correct when moving the mouse of the .canvas-container in the Butterfly builder, just not the X coordinate. How to fix this in Safari?

To see what I mean, please visit: http://memorial.garden and click on the "Launch Butterfly Builder" button on the bottom right hand side of the page. Once you get to Step 2, and choose a color palette, you will see the problem with the pBrush element. Not sure why this is happening with the x coordinate being off like that.

Butterfly Builder Custom Custor Problem in Safari


Solution

  • I won't go into the details, because it is very well documented here: Position:fixed element within a position:relative parent. Which browser renders correctly?

    Basically, the problem is the way that the browsers treat position:fixed; elements.

    To solve this issue, use position: relative; in your #pBrush LESS.

    #pBrush {
        width: 24px;
        height: 34px;
        background: transparent url('../images/paintBrush.png') left bottom no-repeat;
        position: relative;
    
        .color {
            position: absolute;
            width: 12px;
            height: 12px;
            border: 1px solid #FFFFFF;
            display: inline-block;
            top: 0;
            right: 0;
            left: 0;
            margin: 0 auto;
        }
    }
    

    And in your JavaScript, compensate based on the offset of your canvas

    pBucketHTML.css('left', e.pageX - $("#canvasBuilder").offset().left - (pBucketHTML.width() / 2));
    

    You may have to tweak this slightly, but I believe that is what you are looking for.


    Edit: In case a hacky work-around for Safari 8 is acceptable, adapted from How to detect my browser version and operating system using JavaScript?:

    function returnSafariOffset() {
      var nAgt = navigator.userAgent;
    
      // We have Safari
      if ((verOffset=nAgt.indexOf("Safari"))!=-1) {
        fullVersion = nAgt.substring(verOffset+7);
        if ((verOffset=nAgt.indexOf("Version"))!=-1) {
          fullVersion = nAgt.substring(verOffset+8);
        }
    
        majorVersion = parseInt(''+fullVersion,10);
        if (isNaN(majorVersion)) {
          fullVersion  = ''+parseFloat(navigator.appVersion); 
          majorVersion = parseInt(navigator.appVersion,10);
        }
    
        if (majorVersion == 8) {
          // Return a custom amount for Safari 8:
          return $("#canvasBuilder").offset().left;
        }
      }
      // Return an amount for all other browsers:
      return 0;
    }
    

    Then in your JavaScript, you can do something like this:

    pBucketHTML.css('left', e.pageX - returnSafariOffset() - (pBucketHTML.width() / 2));
    

    Since you don't seem to be getting the same results as me, you may have to experiment with some form of this to get exactly what you are looking for. Let me know if you have questions.