01: <svg version="1.1" baseProfile="full" 02: xmlns="http://www.w3.org/2000/svg" 03: width="510px" height="210px" viewBox="0 0 510 210" 04: stroke="black" stroke-width="0.5px" 05: onmousemove="moveEyes(evt)"> 06: 07: <script> 08: // <![CDATA[ 09: 10: var svgNS = "http://www.w3.org/2000/svg"; 11: var xlinkNS = "http://www.w3.org/1999/xlink"; 12: 13: function moveEyes(evt){ 14: 15: // Get the mouse location: 16: var mousex = evt.clientX; 17: var mousey = evt.clientY; 18: 19: // Work out correct pupil position for left eye, and update: 20: var dx=mousex-105; 21: var dy=mousey-105; 22: var dist = Math.sqrt(dx*dx + dy*dy); 23: if (dist > 70) { 24: dx = dx*70/dist; 25: dy = dy*70/dist; 26: } 27: var left=document.getElementById("LeftPupil"); 28: left.setAttributeNS(null, "cx", dx+105); 29: left.setAttributeNS(null, "cy", dy+105); 30: 31: // Work out correct pupil position for right eye, and update: 32: var dx=mousex-405; 33: var dy=mousey-105; 34: var dist = Math.sqrt(dx*dx + dy*dy); 35: if (dist > 70) { 36: dx = dx*70/dist; 37: dy = dy*70/dist; 38: } 39: var right=document.getElementById("RightPupil"); 40: right.setAttributeNS(null, "cx", dx+405); 41: right.setAttributeNS(null, "cy", dy+105); 42: } 43: 44: // ]]> 45: </script> 46: 47: <circle r="100" cx="105" cy="105" stroke="black" stroke-width="10px" fill="white"/> 48: <circle r="100" cx="405" cy="105" stroke="black" stroke-width="10px" fill="white"/> 49: <circle id="LeftPupil" r="20" cx="105" cy="105" fill="black"/> 50: <circle id="RightPupil" r="20" cx="405" cy="105" fill="black"/> 51: 52: </svg>
The important thing to take away from the above example is that in lines 16 and 17 we get the position of the mouse from the pointer. The values of evt.clientX evt.clientY are the number of x- and y-coordinates of the mouse's location measured in pixels from the edge of the graphic.
The reason for the error is that the standard coordinates of the SVG are now 50% larger than a pixel.
01: <svg version="1.1" baseProfile="full" 02: xmlns="http://www.w3.org/2000/svg" 03: width="765px" height="315px" viewBox="0 0 510 210" 04: stroke="black" stroke-width="0.5px" 05: onmousemove="moveEyes(evt)"> 06: 07: <script> 08: // <![CDATA[ 09: 10: var svgNS = "http://www.w3.org/2000/svg"; 11: var xlinkNS = "http://www.w3.org/1999/xlink"; 12: 13: function moveEyes(evt){ 14: 15: // Get the mouse location: 16: var mousex = evt.clientX; 17: var mousey = evt.clientY; 18: 19: // Work out correct pupil position for left eye, and update: 20: var dx=mousex-105; 21: var dy=mousey-105; 22: var dist = Math.sqrt(dx*dx + dy*dy); 23: if (dist > 70) { 24: dx = dx*70/dist; 25: dy = dy*70/dist; 26: } 27: var left=document.getElementById("LeftPupil"); 28: left.setAttributeNS(null, "cx", dx+105); 29: left.setAttributeNS(null, "cy", dy+105); 30: 31: // Work out correct pupil position for right eye, and update: 32: var dx=mousex-405; 33: var dy=mousey-105; 34: var dist = Math.sqrt(dx*dx + dy*dy); 35: if (dist > 70) { 36: dx = dx*70/dist; 37: dy = dy*70/dist; 38: } 39: var right=document.getElementById("RightPupil"); 40: right.setAttributeNS(null, "cx", dx+405); 41: right.setAttributeNS(null, "cy", dy+105); 42: } 43: 44: // ]]> 45: </script> 46: 47: <circle r="100" cx="105" cy="105" stroke="black" stroke-width="10px" fill="white"/> 48: <circle r="100" cx="405" cy="105" stroke="black" stroke-width="10px" fill="white"/> 49: <circle id="LeftPupil" r="20" cx="105" cy="105" fill="black"/> 50: <circle id="RightPupil" r="20" cx="405" cy="105" fill="black"/> 51: 52: </svg>
As we have discussed, each element (or tag) of the SVG document has a local coordinate system. From any element, we can extract a matrix which describes how to convert from local coordinates to screen coordinates (measured in pixels from the left and top). We can use this to update the coordinates.
01: <svg version="1.1" baseProfile="full" 02: xmlns="http://www.w3.org/2000/svg" 03: width="765px" height="315px" viewBox="0 0 510 210" 04: stroke="black" stroke-width="0.5px" 05: onmousemove="moveEyes(evt)"> 06: 07: <script> 08: // <![CDATA[ 09: 10: var svgNS = "http://www.w3.org/2000/svg"; 11: var xlinkNS = "http://www.w3.org/1999/xlink"; 12: 13: function moveEyes(evt){ 14: 15: // Get the mouse location: 16: var position = document.rootElement.createSVGPoint(); 17: position.x = evt.clientX; 18: position.y = evt.clientY; 19: var matrix = document.rootElement.getScreenCTM(); 20: var correctPosition=position.matrixTransform(matrix.inverse()); 21: var mousex = correctPosition.x; 22: var mousey = correctPosition.y; 23: 24: // Work out correct pupil position for left eye, and update: 25: var dx=mousex-105; 26: var dy=mousey-105; 27: var dist = Math.sqrt(dx*dx + dy*dy); 28: if (dist > 70) { 29: dx = dx*70/dist; 30: dy = dy*70/dist; 31: } 32: var left=document.getElementById("LeftPupil"); 33: left.setAttributeNS(null, "cx", dx+105); 34: left.setAttributeNS(null, "cy", dy+105); 35: 36: // Work out correct pupil position for right eye, and update: 37: var dx=mousex-405; 38: var dy=mousey-105; 39: var dist = Math.sqrt(dx*dx + dy*dy); 40: if (dist > 70) { 41: dx = dx*70/dist; 42: dy = dy*70/dist; 43: } 44: var right=document.getElementById("RightPupil"); 45: right.setAttributeNS(null, "cx", dx+405); 46: right.setAttributeNS(null, "cy", dy+105); 47: } 48: 49: // ]]> 50: </script> 51: 52: <circle r="100" cx="105" cy="105" stroke="black" stroke-width="10px" fill="white"/> 53: <circle r="100" cx="405" cy="105" stroke="black" stroke-width="10px" fill="white"/> 54: <circle id="LeftPupil" r="20" cx="105" cy="105" fill="black"/> 55: <circle id="RightPupil" r="20" cx="405" cy="105" fill="black"/> 56: 57: </svg>
The significant code in in lines 15-21. The coordinate change is captured by the root (<svg>) element. There is a coordinate change going on to adjust for the fact that the image dimensions are 50% larger than the local coordinates.
We deal with this in a standard way. We create an object called a SVGPoint in line 16, and we set its x and y coordinates in lines 17-18. Then we find the matrix which changes coordinates from the SVG's coordinates to the screen coordinates (pixels from the left and top border of the image). We actually want to convert the other way, which we do in line 20 by taking an inverse to the matrix and applying it to the mouse position. Then we extract the new coordinate values in lines 21 and 22.