こんにちは。きんくまです。
今回は座標変換です。
座標変換は、ローカル座標からグローバル座標に変換したり、その逆のパターンがあります。
それでgなどが入れ子状態になっていて、それぞれがtransformされている中に入っている子供の要素の座標(ローカル座標)から、SVGからみたときの座標(グローバル座標)に変換したかったです。
参考サイトなど
>> SVG localToGlobal – JSFiddle
>> SVG coordinates with transform matrix
getCTM()を使って変換行列を取得する
そのような入れ子状態だとしても、getCTM() を使うと SVGの座標に変換してくれる行列が手に入ります。
変換するときは matrixTransform() を使います。
サンプルコード
こんな感じに、transformされたgの中にあるcirlceがあるとします。
青が元の座標においたもの、赤がgの中に入ったので移動したものです。
最近知ったのですが、cssのtransformは中に scale translate みたいに連続で変換を書けるんですね。matrixを使わないといけないと思ってました。
html
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" id="sample_svg" width="300" height="300"> <circle cx="80" cy="120" r="10" fill="blue" id="original_circle"></circle> <g transform="scale(1.5, 1.5) translate(50, 30)"> <circle cx="80" cy="120" r="10" fill="red" id="transformed_circle"></circle> </g> </svg>
座標変換のJS
function addCircleToSamePoint(){ const xmlns = 'http://www.w3.org/2000/svg'; const svg = document.getElementById('sample_svg'); const transformedCircle = document.getElementById('transformed_circle'); var localCircleX = transformedCircle.getAttribute('cx'); var localCircleY = transformedCircle.getAttribute('cy'); console.log(localCircleX, localCircleY); //=> 100 150 const point = svg.createSVGPoint(); point.x = localCircleX; point.y = localCircleY; //この行列をかけるとSVGの座標に変換される const matrix = transformedCircle.getCTM(); //SVGからみたtransformedCircleの座標 const svgPoint = point.matrixTransform(matrix); console.log(svgPoint); //=> SVGPoint {x: 225, y: 270} //同じ位置に緑のcircleを入れる //作るときはnamespaceが違うのでcreateElementNSを使う const newCircle = document.createElementNS(xmlns, 'circle'); newCircle.setAttribute('cx', svgPoint.x); newCircle.setAttribute('cy', svgPoint.y); newCircle.setAttribute('r', 30); newCircle.setAttribute('opacity', 0.5); newCircle.setAttribute('fill', 'green'); svg.appendChild(newCircle); } window.onload = function(){ addCircleToSamePoint(); };
今回は座標変換したあとに、svgの直下に同じ位置になるように半透明にした緑の円を置いてみました。
位置もぴったり合っていました。
IE11やその他のモダンブラウザでも動きました。
座標変換は面倒なんですが、分かってよかったです。
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ