Gowrishankar RJ
Gowrishankar RJ

Reputation: 171

svg path gets scribling ,when drawing on line at mozila firefox

Is there is anyway stop the scribling

normal(chrome) image:

enter image description here

scribled image(firefox):

enter image description here

I am using code to generate drawing path

document.createElementNS(NS, "path");

Here is the JsFiddle : JSFIDDLE

Upvotes: 0

Views: 57

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101800

The problem here seems to be a difference between how offsetX and offsetY are implemented between Chrome and Firefox.

In Firefox, when you cross the red line, the offsetX and offsetY values being returned are relative to the top-left of the red line, not the SVG. Which is why your line values are jumping to the top of the screen and left a bit.

I am not sure whether this is a bug in Firefox or not.

In any case, you should not really be using offsetX and offsetY for this purpose. The "correct" approach is normally to get the clientX and clientY coords and translate them to SVG coordinates.

function screenToSVG(clientX, clientY)
{
  // Create an SVGPoint for future math
  var pt = svg.createSVGPoint();
  pt.x = clientX;
  pt.y = clientY;

  // Apply the inverse of the CTM (SVG Current Transform Matrix) to get
  // the equivalent point in SVG coordinate space
  return pt.matrixTransform(svg.getScreenCTM().inverse());
}

The advantage of this approach is that it works even if the SVG is not drawn at 1:1 scale. For example if it has a viewBox.

(function() {
    var stage = jQuery('#stage');
    var isMouseDown = false;
    var NS = "http://www.w3.org/2000/svg";
    var penCount = 0;
    stage.on('mousedown', mouseDown);
    stage.on('mousemove', mouseMove);
    stage.on('mouseup', mouseUp);
    $('#stageClear').on('click',()=>{
    $('.shape').remove()
    })

    function mouseDown(event) {
        var pt = screenToSVG(event.clientX, event.clientY);
        isMouseDown = true;
        var shape = document.createElementNS(NS, "path");
        shape.setAttribute("class", "shape");
        shape.setAttribute("fill", "transparent");
        shape.setAttribute("id", "pen" + penCount);
        shape.setAttribute("stroke", "#2795ee");
        shape.setAttribute("stroke-width", "4px");
        shape.setAttribute("strokeLinecap", "round");
        shape.setAttribute("d", "M " + pt.x + " " + pt.y + " ");
        shape.setAttribute("pointer-events", "none");
        stage.append(shape);
        ++penCount;
    }

    function mouseMove(event) {
        var pt = screenToSVG(event.clientX, event.clientY);
        if (isMouseDown) {
            var depth = jQuery('#pen' + (penCount - 1)).attr("d");
            jQuery('#pen' + (penCount - 1)).attr("d", depth + "L " + pt.x + " " + pt.y + " ");
        }
    }

    function mouseUp(event) {
        isMouseDown = false;
    }
    
    function screenToSVG(clientX, clientY)
    {
        // Create an SVGPoint for future math
        var svg = stage[0];
        var pt = svg.createSVGPoint();
        pt.x = clientX;
        pt.y = clientY;
    
        // Apply the inverse of the CTM (SVG Current Transform Matrix) to get
        // the equivalent point in SVG coordinate space
        return pt.matrixTransform(svg.getScreenCTM().inverse());
    }

})();
#stage{
  width:100%;
  height:610px;
  border:1px solid;
}
#stageClear{
 cursor:pointer;
}
#stagetext{
  user-select:none;
  -moz-user-select:none;
  -ms-user-select:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg id="stage" >
<text id="stagetext" x="10" y="10px">draw on the stage using mouse</text>
  <line x1="50" y1="300" x2="800" y2="300" style="stroke:rgb(255,0,0);stroke-width:2" />
</svg>
<button id="stageClear"> clear</button>

Upvotes: 2

Related Questions