Native Point On Transformed Element: getCTM vs getScreenCTM
http://svgdiscovery.com/E/Ed.htm
http://www.carto.net/svg/eventhandling/
http://stackoverflow.com/questions/5901607/svg-coordiantes
Native Point On Transformed Element: getCTM vs getScreenCTM
Scenerio: 1.) SVG image is inline, contained in a DIV. 2.) The blue rect element is contained in a <g>. 3.) The <g> element has been transformed. 4.) The maroon rect resides in a different viewPort. 5.) The orange circle have been transformed. 5.) The red circle is not transformed. 6.) Click at element to show its native point. redCircle clicked: black circle to its center.
blueRect clicked: black circle to its corner.
maroonRect clicked: black circle to its corner.
orangeCircle clicked: black circle to its center.
*This feature works only if the SVG ViewBox,or its width/height is the same size as the DIV
The black circle receive the transform of the clicked element,
and it will be placed at the 'native' point clicked. |
Target:
|
SVG Source:
Javascript:
Native Point On Transformed Element: getCTM vs getScreenCTM
Scenerio: 1.) SVG image is inline, contained in a DIV. 2.) The blue rect element is contained in a <g>. 3.) The <g> element has been transformed. 4.) The maroon rect resides in a different viewPort. 5.) The orange circle have been transformed. 5.) The red circle is not transformed. 6.) Click at element to show its native point. redCircle clicked: black circle to its center.
blueRect clicked: black circle to its corner.
maroonRect clicked: black circle to its corner.
orangeCircle clicked: black circle to its center.
*This feature works only if the SVG ViewBox,or its width/height is the same size as the DIV
The black circle receive the transform of the clicked element,
and it will be placed at the 'native' point clicked. |
Target:
|
<svg id="mySVG" width="400" height="400" onclick="showCTM(evt)" onmousemove="svgCursor(evt)">
<rect id="bbRect" stroke="black" stroke-width="1" fill="yellow" fill-opacity=".5"></rect>
<circle id="redCircle" cx="120" cy="180" r="40" fill="red" stroke="black" stroke-width="2"></circle>
<circle transform="matrix(0.5, 1.15195, 0, 0.9, 180, -260)" id="orangeCircle" cx="200" cy="200" r="40" fill="orange" stroke="black" stroke-width="2"></circle>
<svg viewBox="0 100 800 800">
<rect id="maroonRect" x="200" y="200" width="160" height="60" fill="maroon" stroke="black" stroke-width="2"></rect>
</svg>
<g transform="matrix(1.08446, 0.815207, -0.316712, 0.68404, 69.5454, -107.056)" id="myG">
<rect id="blueRect" x="220" y="250" width="60" height="60" fill="blue" stroke="black" stroke-width="2"></rect>
</g>
<circle id="blackCircle" r="10" fill="black"></circle>
</svg>
document.onmousemove = htmCursor
//---'event' is the html event object---
function htmCursor(event)
{
var event = event || window.event;
myMouseX=event.clientX;
myMouseY=event.clientY;
htmlOffsetXValue.value = myMouseX + document.documentElement.scrollLeft;
htmlOffsetYValue.value = myMouseY + document.documentElement.scrollTop;
}
//---mouse move---
//---'evt' is the svg event object--
function svgCursor(evt)
{
var pnt = mySVG.createSVGPoint();
pnt.x = evt.clientX;
pnt.y = evt.clientY;
var svgCTM=mySVG.getScreenCTM();
var iPNT = pnt.matrixTransform(svgCTM.inverse());
SvgXValue.value=rnd2(iPNT.x)
SvgYValue.value=rnd2(iPNT.y)
}
//---mouse click---
function showCTM(evt)
{
var target=evt.target
elemIdValue.value=target.id
var pnt = mySVG.createSVGPoint();
pnt.x = evt.clientX;
pnt.y = evt.clientY;
var SCTM = target.getScreenCTM();
var iPNT = pnt.matrixTransform(SCTM.inverse());
SCTMXValue.value=rnd2(iPNT.x)
SCTMYValue.value=rnd2(iPNT.y)
if(ctmRadio.checked==true)
placeBlackCircle(target)
else if(sctmRadio.checked==true)
sendBlackCircle(evt)
}
//---this feature works only if the svg viewBox is same as DIV width/height--
function placeBlackCircle(target)
{
blackCircle.removeAttribute("transform")
var pnt = mySVG.createSVGPoint();
if(target.id=="redCircle" ||target.id=="orangeCircle")
{
pnt.x=parseFloat(target.getAttribute("cx"))
pnt.y=parseFloat(target.getAttribute("cy"))
}
if(target.id=="blueRect" ||target.id=="maroonRect")
{
pnt.x=parseFloat(target.getAttribute("x"))
pnt.y=parseFloat(target.getAttribute("y"))
}
var CTM=target.getCTM()
//---get related svg image x,y---
var PNT = pnt.matrixTransform(CTM);
blackCircle.setAttribute("cx",PNT.x)
blackCircle.setAttribute("cy",PNT.y)
}
function sendBlackCircle(evt)
{
blackCircle.removeAttribute("transform")
var target=evt.target;
//---initialize a point in its respective viewport--
if(target.nearestViewportElement) //--must click on an element not svg root--
{
var pnt = target.nearestViewportElement.createSVGPoint();
//---client area click point---
pnt.x = evt.clientX;
pnt.y = evt.clientY;
var sCTM = target.getScreenCTM();
//---return viewport's Pnt.x, Pnt.y---
PNT = pnt.matrixTransform(sCTM.inverse());
//----place blackDot on top in viewport and locate it---
target.nearestViewportElement.appendChild(blackCircle)
blackCircle.setAttribute("cx",PNT.x)
blackCircle.setAttribute("cy",PNT.y)
if(target.parentNode.nodeName=="g")
{
target.parentNode.appendChild(blackCircle)
}
if(target.getAttribute("transform"))
{
var transform=target.getAttribute("transform")
blackCircle.setAttribute("transform",transform)
}
else
blackCircle.removeAttribute("transform")
}
}
function rnd2(num)
{
return Math.round(num*100)/100
}
//---onload---
function initTransforms()
{
//---place some transforms on the elements---
//--- transform orange circle---
var transformRequestObj=mySVG.createSVGTransform()
var animTransformList=orangeCircle.transform
var transformList=animTransformList.baseVal
//---translate---
transformRequestObj.setTranslate(180,-260)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//----scale---
transformRequestObj.setScale(.5,.9)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//----skewY---
transformRequestObj.setSkewY(52)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//--init Transform on myG---
var transformRequestObj=mySVG.createSVGTransform()
var animTransformList=myG.transform
var transformList=animTransformList.baseVal
//---translate---
transformRequestObj.setTranslate(-50,-80)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//----skewX---
transformRequestObj.setSkewX(15)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//----skewY---
transformRequestObj.setSkewY(20)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//---rotate---
transformRequestObj.setRotate(30,200,200)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
}