'How can I prevent 2 svg paths from being connected?
I am creating some kind of signature field, but I have the following unwanted behavior: when I draw for example 2 lines, at the beginning the second one looks like it is trying to connect to the first one and my question is how can I prevent that?
...in the example below I actually tried to draw 3 lines.
... Edit: I've edited and improved the example below based on the suggestions from @Danny'365CSI'Engelman and @chrwahl and it now works for both desktop and mobile.
let signature = document.getElementById('signature');
if (signature) {
const appendNewSvgPath = function (e) {
if (e.buttons === 1) {
let intiialXY = ` ${e.offsetX} ${e.offsetY}`;
svgpath = document.createElementNS("http://www.w3.org/2000/svg", "path");
svgpath.setAttribute('d', `M${intiialXY} C${intiialXY.repeat(3)}`);
signature.append(svgpath);
}
};
const drawToSvgPath = function (e) {
if (e.buttons === 1) {
params.push(e.offsetX);
params.push(e.offsetY);
if (params.length === 6) {
let d = svgpath.getAttribute('d');
svgpath.setAttribute('d', `${d} ${params.join(' ')}`);
params = [];
}
}
};
const clearPathParams = _ => params = [];
let svgpath;
let params = [];
signature.onmousedown = appendNewSvgPath;
signature.onpointerdown = appendNewSvgPath;
signature.onmousemove = drawToSvgPath;
signature.onpointermove = drawToSvgPath;
signature.onmouseout = clearPathParams;
signature.onpointerout = clearPathParams;
signature.onmouseenter = appendNewSvgPath;
signature.onpointerenter = appendNewSvgPath;
signature.onmouseup = clearPathParams;
signature.onpointerup = clearPathParams;
}
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
height: 100vh;
overflow: hidden;
background-color: whitesmoke;
}
#signature {
display: block;
width: 800px;
height: 300px;
border: none;
background-color: white;
touch-action: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<svg id="signature" stroke="blue" stroke-width="2" stroke-linecap="round" fill="none"></svg>
</body>
</html>
Solution 1:[1]
In some cases the params array is not empty when when the mousedown event happens because the array is only emptied when it has the length of 6 (in the mousemove event listener). To avoid a partly filled array you should empty it on the mouse up event.
let signature = document.getElementById('signature');
let svgpath;
let params = [];
if (signature) {
signature.addEventListener('mousedown', e => {
if (e.buttons === 1) {
svgpath = document.createElementNS("http://www.w3.org/2000/svg", "path");
svgpath.setAttribute('d', `M ${e.offsetX} ${e.offsetY}`);
signature.append(svgpath);
}
});
signature.addEventListener('mousemove', e => {
if (e.buttons === 1) {
params.push(e.offsetX);
params.push(e.offsetY);
if (params.length == 6) {
let d = svgpath.getAttribute('d');
svgpath.setAttribute('d', `${d} C ${params.join(' ')}`);
params = [];
}
}
});
signature.addEventListener('mouseup', e => {
params = [];
});
}
body {
margin: 0;
padding: 0;
background-color: whitesmoke;
}
#signature {
display: block;
width: 800px;
height: 300px;
border: none;
background-color: white;
}
<svg id="signature" stroke="blue" stroke-width="2" stroke-linecap="round" fill="none"></svg>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

