I was working on an application to track movement in an SVG viewbox relative to the size of the SVG element itself. The sample code below has been reduced to remove any extra functions, variables, calculations, etc. as much as possible to demonstrate just the problem.
When moving the mouse cursor across the SVG, the green pointer tracker shits its x & y positions by 10px each when moving through the approximate zones marked by the red bands. Also moving left to right vs. right to left has slightly different trigger points.
const pointerMove = event => {
// console.log(event.offsetX);
const id = 'pointer';
const pointerOld = document.getElementById(id);
if (pointerOld) pointerOld.remove();
const x = event.offsetX;
const y = event.offsetY;
const pointerNew = document.createElementNS(svg.namespaceURI, 'circle');
pointerNew.setAttributeNS(null, 'id', id);
pointerNew.setAttributeNS(null, 'cx', x * 0.25);
pointerNew.setAttributeNS(null, 'cy', y * 0.5);
pointerNew.setAttributeNS(null, 'r', '15px');
pointerNew.setAttributeNS(null, 'stroke', 'green');
pointerNew.setAttributeNS(null, 'stroke-width', '5px');
pointerNew.setAttributeNS(null, 'fill', 'none');
svg.append(pointerNew);
}
const svg = document.getElementById('svg1');
svg.addEventListener('pointermove', pointerMove);
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 100" width="400" height="200" style="border: 2pt solid;">
<line x1="0" y1="0" x2="100px" y2="100" stroke="blue" />
<line x1="100" y1="0" x2="0" y2="100" stroke="blue" />
<rect x="14" y="0" width="1" height="100" fill="red"></rect>
<rect x="16" y="0" width="1" height="100" fill="red"></rect>
<rect x="18" y="0" width="1" height="100" fill="red"></rect>
<rect x="20" y="0" width="1" height="100" fill="red"></rect>
<rect x="22" y="0" width="12" height="100" fill="red"></rect>
<rect x="75" y="0" width="1" height="100" fill="red"></rect>
<rect x="77" y="0" width="12" height="100" fill="red"></rect>
</svg>
I found some “work-arounds” including:
- If I uncomment the
console.log(event.offsetX);
line, it performs fine. - If I move the x & y constant declarations before the
if (pointerOld) pointerOld.remove();
line, it also works fine.
However, I am trying to understand why it is behaving like this in the first place? Am I doing something wrong? Or is this a bug (in HTML/JavaScript/SVG/web browser/OS)?