Reputation: 171
Is there is anyway stop the scribling
normal(chrome) image:
scribled image(firefox):
I am using code to generate drawing path
document.createElementNS(NS, "path");
Here is the JsFiddle : JSFIDDLE
Upvotes: 0
Views: 57
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