I'm using the svg jquery plugin by Keith Wood, not the HTML5 canvas.
I define my svg image like this to scale my svg triangle image to fit its div container:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" viewBox="0 0 299 215" >
<g>
<polygon points="1,1 299,1 149,210" fill="blue" stroke="blue" stroke-width="0" class="votenow"/>
</g>
</svg>
But how do I then match the coordinate systems?
I want to capture the mouse location at some point over the triangle and draw a circle at those X Y coordinates, but the circle gets drawn in a different location because the coordinate systems don't match.
So a circle would be drawn at point 10,10 but appear to be at 50,60 for example.
How do people cope with this?
Thanks.
Final Solution: Using the JQuery plugin to draw the circle and getScreenCTM() to calculate the points.
Perhaps I no longer require the JQuery plugin but it will do for now. Couldn't see how to do it using only the plugin.
$('#cvtriangle .tri').on( "click", function(e) {
jqsvg = $('#cvtriangle').svg('get');
svg = document.querySelector("svg");
var pt = svg.createSVGPoint();
pt.x = e.clientX;
pt.y = e.clientY;
pt = pt.matrixTransform(svg.getScreenCTM().inverse());
jqsvg.circle(pt.x, pt.y, 5, {class: 'vote', fill: 'white', stroke: 'white', strokeWidth: 2, cursor: 'pointer'});
});
See http://msdn.microsoft.com/en-us/library/hh535760%28v=vs.85%29.aspx It's my sample code. For this usage, getScreenCTM method is very useful.
<svg viewBox="0 0 300 300" onload="
var c = document.getElementById('c');
var cx = c.cx.baseVal;
var cy = c.cy.baseVal;
var svg = this;
var point = svg.createSVGPoint();
svg.onmousemove = function(e){
point.x = e.clientX;
point.y = e.clientY;
var ctm = c.getScreenCTM();
var inverse = ctm.inverse();
var p = point.matrixTransform(inverse);
cx.value = p.x;
cy.value = p.y;
};
">
<rect width="100%" height="100%" fill="yellow"/>
<circle id="c" r="10" fill="blue"/>
</svg>
If you call the function getScreenCTM()
on the SVG element, it will return the transform matrix used to convert document coordinates to screen coordinates. You want the transform matrix for the other direction, so call inverse()
on the matrix object.
var transform = svg.getScreenCTM().inverse();
Now you can transform a point object to do the final conversion:
pt = pt.matrixTransform(transform);
Working demo here
var x = document.getElementById("x"),
y = document.getElementById("y"),
svg = document.querySelector("svg");
svg.addEventListener("mousemove", function(evt) {
var pt = svg.createSVGPoint();
pt.x = evt.pageX;
pt.y = evt.pageY;
pt = pt.matrixTransform(svg.getScreenCTM().inverse());
x.innerHTML = pt.x;
y.innerHTML = pt.y;
}, false);
#container {
width: 200px;
height: 200px;
}
div {
float: left;
margin-left: 1em;
}
<div id="container">
<svg version="1.0" viewbox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="blue"/>
</svg>
</div>
<div>
x = <span id="x"></span><br/>
y = <span id="y"></span>
</div>
If the above version (using pageX/Y) doesn't work for you, try this version instead.
var x = document.getElementById("x"),
y = document.getElementById("y"),
svg = document.querySelector("svg");
svg.addEventListener("mousemove", function(evt) {
var pt = svg.createSVGPoint();
pt.x = evt.clientX;
pt.y = evt.clientY;
pt = pt.matrixTransform(evt.target.getScreenCTM().inverse());
x.innerHTML = pt.x;
y.innerHTML = pt.y;
}, false);
#container {
width: 200px;
height: 200px;
}
div {
float: left;
margin-left: 1em;
}
<div id="container">
<svg version="1.0" viewbox="0 0 100 100">
<rect x="0" y="0" width="100" height="100" fill="blue"/>
</svg>
</div>
<div>
x = <span id="x"></span><br/>
y = <span id="y"></span>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With