LoginSignup
0
3

More than 1 year has passed since last update.

SVG周りの座標変換まとめ

Posted at

座標変換を理解するために、次のようなDOM構造を考えます。
(複雑さを排除するため、x と y(または width と height)は同じ値にしています)

export function Component() {
  return (
    <div style={{ margin: 100 }}>
      <svg width={200} height={200} viewBox="0 0 400 400">
        <g transform="translate(100, 100)"></g>
      </svg>
    </div>
  );
}

このDOM構造には、いくつかの座標系が存在します。
これら座標系間の変換にはどの行列を使えば良いかについては、次の図を見ることでわかります。
(図の数値は x 座標を表します)

ctm.drawio.png

たとえば、座標系 D の点 (150, 150) を座標系 B の点に変換するときは、次のように実装します。

const p = new DOMPoint(150, 150);
const m = g.getCTM()!;
const q = p.matrixTransform(m);
console.log(q.x); //=> 125

g.getCTM()svg.getScreenCTM() の評価値は DOMMatrix オブジェクト(または null)です。
DOMMatrix オブジェクトは .inverse() メソッドを持ちます。
これは逆行列を返すメソッドです。これを利用することで、座標系 B から座標系 D への変換などが可能になります。
次のように実装します。

const p = new DOMPoint(125, 125);
const m = g.getCTM()!.inverse();
const q = p.matrixTransform(m);
console.log(q.x); //=> 150

座標系 D から座標系 C に変換するときは次のように実装します。

const p = new DOMPoint(300, 300);
const m1 = g.getCTM()!;
const q = p.matrixTransform(m1);
const m2 = svg.getCTM()!.inverse();
const r = q.matrixTransform(m2);
console.log(r.x); //=> 400

次のように、変換行列同士の積を取り、その行列を適用することもできます。

const p = new DOMPoint(300, 300);
const m = (() => {
  const m1 = g.getCTM()!;
  const m2 = svg.getCTM()!.inverse();
  return m2.multiply(m1);
})();
const q = p.matrixTransform(m);
console.log(q.x); //=> 400
0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3