SVGMatrix について
■ SVGMatrix について
Scalable Vector Graphics (SVG) の機能の1つです。
http://www.w3.org/TR/SVG11/coords.html#InterfaceSVGMatrix
SVGMatrix は、3行2列のマトリックスです。
2D用のアフィン行列を表現できます。
■プロパティについて
プロパティ名 | 型 | 説明 | 番地 |
a | Number | x 軸成分の x 座標 | [0][0] |
b | Number | x 軸成分の y 座標 | [1][0] |
c | Number | y 軸成分の x 座標 | [0][1] |
d | Number | y 軸成分の y 座標 | [1][1] |
e | Number | 座標成分の x 座標 | [0][2] |
f | Number | 座標成分の y 座標 | [1][2] |
■行列の並びについて
行列の並びは、OpenGL と同等です。
行列の並び方
var mtx33 = [
[ a , c , e ],
[ b , d , f ],
[ 0 , 0 , 1 ]
];
■各プロパティを確認する
赤色のベクトル (a , b) が、x 軸成分です。
青色のベクトル (c , d) が、y 軸成分です。
赤と青ベクトルの交差位置 (e , f) は、座標成分です。
■行列の合成(乗算)順序について
乗算順序を入れ替えると、合成結果は変化します。
自身の行列は、2通りのアプローチで、少しずつ姿勢を変更できます。
以下の順序で乗算した場合、差分はグローバル座標系に作用します。
(自身の行列) = (新しい差分) * (自身の行列)
以下の順序で乗算した場合、差分はローカル座標系に作用します。
(自身の行列) = (自身の行列) * (新しい差分)
SVGMatrix オブジェクトを作成する
■SVGMatrix オブジェクトを作成する
SVGSVGElement の createSVGMatrix() メソッドを使用します。
デフォルトの状態で、単位行列です。
SVGSVGElement.createSVGMatrix ( ) :SVGMatrix
引数 | Void | なし。 |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■ SVGMatrix オブジェクトを作成する関数
SVGMatrix オブジェクトを作成する関数
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する関数
// ------------------------------------------------------------
function SVGMatrixCreate(a,b,c,d,e,f){
var svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
var mtx = svg.createSVGMatrix();
if(a !== undefined) mtx.a = a;
if(b !== undefined) mtx.b = b;
if(c !== undefined) mtx.c = c;
if(d !== undefined) mtx.d = d;
if(e !== undefined) mtx.e = e;
if(f !== undefined) mtx.f = f;
return mtx;
}
■使用例
SVGMatrix オブジェクトを作成する
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// 出力テスト
console.log(mtx); // a:1 , b:0 , c:0 , d:1 , e:0 , f:0
SVGMatrix の計算について
■SVGMatrix の機能一覧
■平行移動メソッド
メソッド | 説明 |
translate() | 並行移動成分を合成する |
■回転メソッド
メソッド | 説明 |
rotate() | 回転成分を合成する(角度指定) |
rotateFromVector() | 回転成分を合成する(ベクトル指定) |
■拡大縮小メソッド
メソッド | 説明 |
scaleNonUniform() | 拡大縮小成分を合成する(軸ごとに指定) |
scale() | 拡大縮小成分を合成する(全体指定) |
flipX() | 水平方向に反転する |
flipY() | 垂直方向に反転する |
■せん断メソッド
■乗算メソッド
メソッド | 説明 |
multiply() | 行列を合成する(乗算する) |
■逆行列メソッド
メソッド | 説明 |
inverse() | 逆行列を計算する |
■並行移動成分を合成する
■並行移動成分を合成する
translate() メソッドを使用します。
以下の順番で乗算されます。
(新しい行列) = (自身の行列) * (並行移動成分)
平行移動成分は、ローカル座標系に作用します。
SVGMatrix.translate ( x , y ) :SVGMatrix
第01引数 | Number | x 座標を指定。 |
第02引数 | Number | y 座標を指定。 |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■使用例
並行移動成分を合成する
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// ------------------------------------------------------------
// 並行移動成分を合成する
// ------------------------------------------------------------
mtx = mtx.translate(100,200);
// 出力テスト
console.log(mtx); // a:1 , b:0 , c:0 , d:1 , e:100 , f:200
■回転成分を合成する(角度指定)
■回転成分を合成する(角度指定)
rotate() メソッドを使用します。
以下の順番で乗算されます。
(新しい行列) = (自身の行列) * (回転成分)
回転成分は、ローカル座標系に作用します。
SVGMatrix.rotate ( angle ) :SVGMatrix
第01引数 | Number | 角度を指定。(単位はデグリー) |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■使用例
回転成分を合成する
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// ------------------------------------------------------------
// 回転成分を合成する
// ------------------------------------------------------------
mtx = mtx.rotate(30);
// 出力テスト
console.log(mtx); // a:0.866 , b:0.499 , c:-0.499 , d:0.866 , e:0 , f:0
■回転成分を合成する(ベクトル指定)
■回転成分を合成する(ベクトル指定)
rotateFromVector() メソッドを使用します。
以下の順番で乗算されます。
(新しい行列) = (自身の行列) * (回転成分)
回転成分は、ローカル座標系に作用します。
SVGMatrix.rotateFromVector ( x , y ) :SVGMatrix
第01引数 | Number | ベクトルの x 成分を指定。(0.0 指定は不可) |
第02引数 | Number | ベクトルの y 成分を指定。(0.0 指定は不可) |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■エラーが発生する場合
引数に 0 を指定すると、エラーが発生します。
(0 , 0) の場合に限って発生すべきですが、片方が 0 なら発生します。
これにより、rotate() メソッドを使った方が安全です。
■ラジアンからベクトルを計算する
(x) = Math.cos( ラジアン )
(y) = Math.sin( ラジアン )
ラジアンからベクトルに変換する
// 角度
var deg = 30;
// ラジアンに変換
var rad = (deg) * (Math.PI / 180);
// ベクトルに変換
var x = Math.cos(rad);
var y = Math.sin(rad);
■ベクトルからラジアンを計算する
(ラジアン) = Math.atan2( y , x )
ベクトルの長さが 0 である場合、ラジアンの計算は不可能です。
ベクトルからラジアンに変換する
// ベクトル
var x = 1.0;
var y = 0.0;
// ラジアンに変換
var rad = Math.atan2(y , x);
// 角度に変換
var deg = (rad) * (180 / Math.PI);
■使用例
回転成分を合成する(ベクトル指定)
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// ------------------------------------------------------------
// ベクトルを用意する
// ------------------------------------------------------------
// ラジアン
var rad = (30) * (Math.PI / 180);
// ベクトルに変換
var vec_x = Math.cos(rad);
var vec_y = Math.sin(rad);
// ------------------------------------------------------------
// 回転成分を合成する(ベクトル指定)
// ------------------------------------------------------------
mtx = mtx.rotateFromVector(vec_x , vec_y);
// 出力テスト
console.log(mtx); // a:0.866 , b:0.499 , c:-0.499 , d:0.866 , e:0 , f:0
■拡大縮小成分を合成する(軸ごとに指定)
■拡大縮小成分を合成する
scaleNonUniform() メソッドを使用します。
以下の順番で乗算されます。
(新しい行列) = (自身の行列) * (拡大縮小成分)
拡大縮小成分は、ローカル座標系に作用します。
SVGMatrix.scaleNonUniform ( x , y ) :SVGMatrix
第01引数 | Number | x 軸方向の拡大率を指定。(1.0 で等倍) |
第02引数 | Number | y 軸方向の拡大率を指定。(1.0 で等倍) |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■使用例
拡大縮小成分を合成する(軸ごとに指定)
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// ------------------------------------------------------------
// 拡大縮小成分を合成する(軸ごとに指定)
// ------------------------------------------------------------
mtx = mtx.scaleNonUniform(3 , 0.5);
// 出力テスト
console.log(mtx); // a:3 , b:0 , c:0 , d:0.5 , e:0 , f:0
■拡大縮小成分を合成する(全体指定)
■拡大縮小成分を合成する
scale() メソッドを使用します。
以下の順番で乗算されます。
(新しい行列) = (自身の行列) * (拡大縮小成分)
拡大縮小成分は、ローカル座標系に作用します。
SVGMatrix.scale ( scaleFactor ) :SVGMatrix
第01引数 | Number | 全体の拡大率を指定。(1.0 で等倍) |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■使用例
拡大縮小成分を合成する(全体指定)
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// ------------------------------------------------------------
// 拡大縮小成分を合成する(全体指定)
// ------------------------------------------------------------
mtx = mtx.scale(2.5);
// 出力テスト
console.log(mtx); // a:2.5 , b:0 , c:0 , d:2.5 , e:0 , f:0
■水平方向に反転する
■水平方向に反転する
flipX() メソッドを使用します。
以下の行列の乗算と、結果は同等です。
(a:-1 , b:0 , c:0 , d:1 , e:0 , f:0)
反転は、ローカル座標系に作用します。
SVGMatrix.flipX ( ) :SVGMatrix
引数 | Void | なし |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■使用例
水平方向に反転する
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する
// ------------------------------------------------------------
var mtx = SVGMatrixCreate( 2 , 0 , 0 , 4 , 0 , 0 );
// ------------------------------------------------------------
// 水平方向に反転する
// ------------------------------------------------------------
mtx = mtx.flipX();
// 出力テスト
console.log(mtx); // a:-2 , b:0 , c:0 , d:4 , e:0 , f:0
■垂直方向に反転する
■垂直方向に反転する
flipY() メソッドを使用します。
以下の行列の乗算と、結果は同等です。
(a:1 , b:0 , c:0 , d:-1 , e:0 , f:0)
反転は、ローカル座標系に作用します。
SVGMatrix.flipY ( ) :SVGMatrix
引数 | Void | なし |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■使用例
垂直方向に反転する
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する
// ------------------------------------------------------------
var mtx = SVGMatrixCreate( 2 , 0 , 0 , 4 , 0 , 0 );
// ------------------------------------------------------------
// 垂直方向に反転する
// ------------------------------------------------------------
mtx = mtx.flipY();
// 出力テスト
console.log(mtx); // a:2 , b:0 , c:0 , d:-4 , e:0 , f:0
■せん断成分を合成する(y 軸を傾ける)
■せん断成分を合成する(y 軸を傾ける)
skewX() メソッドを使用します。
以下の順番で乗算されます。
(新しい行列) = (自身の行列) * (せん断成分)
せん断成分は、ローカル座標系に作用します。
SVGMatrix.skewX ( angle ) :SVGMatrix
第01引数 | Number | 角度(-90 ~ 90)を指定。(単位はデグリー) |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■せん断行列について
y 軸の x 成分のみが変化します。
(cプロパティ) = Math.tan(angle * (Math.PI / 180));
■使用例
せん断成分を合成する(y 軸を傾ける)
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// ------------------------------------------------------------
// せん断成分を合成する(y 軸を傾ける)
// ------------------------------------------------------------
mtx = mtx.skewX(30);
// 出力テスト
console.log(mtx); // a:1 , b:0 , c:0.577 , d:1 , e:0 , f:0
■せん断成分を合成する(x 軸を傾ける)
■せん断成分を合成する(x 軸を傾ける)
skewY() メソッドを使用します。
以下の順番で乗算されます。
(新しい行列) = (自身の行列) * (せん断成分)
せん断成分は、ローカル座標系に作用します。
SVGMatrix.skewY ( angle ) :SVGMatrix
第01引数 | Number | 角度(-90 ~ 90)を指定。(単位はデグリー) |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■せん断行列について
x 軸の y 成分のみのみが変化します。
(bプロパティ) = Math.tan(angle * (Math.PI / 180));
■使用例
せん断成分を合成する(x 軸を傾ける)
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// ------------------------------------------------------------
// せん断成分を合成する(x 軸を傾ける)
// ------------------------------------------------------------
mtx = mtx.skewY(30);
// 出力テスト
console.log(mtx); // a:1 , b:0.577 , c:0 , d:1 , e:0 , f:0
■行列を合成する(乗算する)
■行列を合成する(乗算する)
multiply() メソッドを使用します。
以下の順番で乗算されます。
(新しい行列) = (自身の行列) * (引数の行列)
引数で指定した行列は、ローカル座標系に作用します。
SVGMatrix.multiply ( second ) :SVGMatrix
第01引数 | SVGMatrix | 2つ目の SVGMatrix オブジェクトを指定。 |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■使用例
複数の行列を合成する
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する(単位行列)
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
// ------------------------------------------------------------
// 位置(100,200) ← 角度(10度) ← 拡大率(2,3) の順番で合成
// ------------------------------------------------------------
// 並行移動成分を合成
mtx = mtx.translate( 100.0 , 200.0 );
// 回転成分を合成
mtx = mtx.rotate( 10.0 );
// 拡大縮小成分を合成
mtx = mtx.scaleNonUniform( 2.0 , 3.0 );
// 出力テスト
console.log(mtx); // a:1.969 , b:0.347 , c:-0.520 , d:2.954 , e:100 , f:200
// ------------------------------------------------------------
// 各行列を作成する
// ------------------------------------------------------------
// 単位行列を作成
mtx = SVGMatrixCreate();
// 並行移動行列を作成
var mtx0 = mtx.translate( 100.0 , 200.0 );
// 回転行列を作成
var mtx1 = mtx.rotate( 10.0 );
// 拡大縮小行列を作成
var mtx2 = mtx.scaleNonUniform( 2.0 , 3.0 );
// ------------------------------------------------------------
// 各行列を順番に合成 (移動 ← 回転 ← 拡大)
// ------------------------------------------------------------
mtx = mtx.multiply( mtx0 );
mtx = mtx.multiply( mtx1 );
mtx = mtx.multiply( mtx2 );
// 出力テスト
console.log(mtx); // a:1.969 , b:0.347 , c:-0.520 , d:2.954 , e:100 , f:200
■逆行列を計算する
■逆行列を計算する
inverse() メソッドを使用します。
SVGMatrix.inverse ( ) :SVGMatrix
引数 | Void | なし。 |
戻り値 | SVGMatrix | 新しい SVGMatrix オブジェクトが得られる。 |
■使用例
逆行列を計算する
// ------------------------------------------------------------
// SVGMatrix オブジェクトを作成する
// ------------------------------------------------------------
var mtx = SVGMatrixCreate();
mtx.a = Math.random() * 2 - 1;
mtx.b = Math.random() * 2 - 1;
mtx.c = Math.random() * 2 - 1;
mtx.d = Math.random() * 2 - 1;
mtx.e = Math.random() * 2 - 1;
mtx.f = Math.random() * 2 - 1;
// ------------------------------------------------------------
// 逆行列を計算する
// ------------------------------------------------------------
var invert_mtx = mtx.inverse();
// ------------------------------------------------------------
// 行列を乗算する
// ------------------------------------------------------------
mtx = mtx.multiply( invert_mtx );
// 出力テスト
console.log(mtx); // a:1 , b:0 , c:0 , d:1 , e:0 , f:0
■座標を変換する
■座標を変換する関数
座標を変換する関数
// ------------------------------------------------------------
// 座標を変換する関数
// ------------------------------------------------------------
function SVGMatrixTransformPosition(matrix,x,y){
return {
x:x * matrix.a + y * matrix.c + matrix.e,
y:x * matrix.b + y * matrix.d + matrix.f
};
}
■ベクトルを変換する
■ベクトルを変換する関数
ベクトルを変換する関数
// ------------------------------------------------------------
// ベクトルを変換する関数
// ------------------------------------------------------------
function SVGMatrixTransformVector(matrix,x,y){
return {
x:x * matrix.a + y * matrix.c,
y:x * matrix.b + y * matrix.d
};
}
SVGMatrix を反映する
■ CSS 2D Transforms に反映する
■ CSS Transforms について
CSS Transforms については、こちらで解説しています。
■ CSS 2D Transform 用の文字列を出力する関数
CSS 2D Transform 用の文字列を出力する関数
// ------------------------------------------------------------
// SVGMatrix から CSS 2D Transform 用の文字列を出力する関数
// ------------------------------------------------------------
function SVGMatrix_ToString_CSSTransform(svg_matrix){
return "matrix(" +
svg_matrix.a.toFixed(20) + "," +
svg_matrix.b.toFixed(20) + "," +
svg_matrix.c.toFixed(20) + "," +
svg_matrix.d.toFixed(20) + "," +
svg_matrix.e.toFixed(20) + "," +
svg_matrix.f.toFixed(20) +
")";
}
■ Canvas 2D Context に反映する
■ Canvas 2D Context について
Canvas 2D Context については、こちらで解説しています。
■ Context2D に SVGMatrix をセットする関数
Context2D に SVGMatrix をセットする関数
// ------------------------------------------------------------
// Context2D に SVGMatrix をセットする関数
// ------------------------------------------------------------
function Context2D_Set_SVGMatrix(context , matrix){
context.setTransform(matrix.a,matrix.b,matrix.c,matrix.d,matrix.e,matrix.f);
}