matrix3d
パースペクティブを与えるために で変換された要素があります。ハンドヘルド デバイスの画面を表します。
ハンドヘルド デバイス自体を示す背景画像があり、これは変換されません。これを保持する要素が配置され、画面要素がその中に完全に配置されleft: 0; top: 0;
、コンテナの左上を起点として変換されます。これは、背景画像と完全に一致させる最も簡単な方法で (マトリックスを作成するためにこの非常に便利なツールを使用しました)、画面要素を隅から離します。
マウスとタッチイベントで画面を操作できるようにしたい。これを行うには、クリック イベントまたはタッチ イベントで、画面要素のローカル座標系で座標を見つける必要があります。つまり、変換が行われる前の座標です。つまり、ハンドヘルド デバイスの画面の左上 (ページ上のバウンディング ボックスの左上ではない[0, 0]
!) をクリックすると、 I want が表示され、画面の右上をクリックすると、このトランスフォームの場合は実際には、ページのさらに上と右側にあります[untransformedWidth, 0]
。
マウス イベントはこれを提供し、正確にこれを行うoffsetX
とoffsetY
言われていますが (詳細は後述)、タッチ イベントにはこれらのプロパティがないため、自分で計算する方法が必要です。
math.jsを使用して、変換行列を入力して反転させることができます。ルールを取得するためにCSS ルールをループするコードがいくつかありますtransform: matrix3d(...)
(必要がなければコード内で繰り返したくありません)。 CSSに合わせます。
CSS には行列要素が列順にあることに注意してください。したがってmatrix3d(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p)
、通常の行列表記では次のようになります。
┌ ┐
│ a e i m │
│ b f j n │
│ c g k o │
│ d h l p │
└ ┘
一方、math.js では、行列を のように行ごとに宣言する必要があり[[a, e, i, m], [b, f, j, n]...
ます。
matrix3d(...)
したがって、式内
の数値要素のリストがあるところから始めて、 CSS の順序で、次のようにマトリックスを作成して反転します。
var rows = [[], [], [], []];
for (var i = 0; i < elements.length; i++) {
rows[i % 4][Math.floor(i / 4)] = elements[i];
}
var matrixTransform = math.matrix(rows);
var invertedMatrixTransform = math.inv(matrixTransform);
次に、画面要素にマウス イベント ハンドラーを設定します。
screen.addEventListener('mousedown', function (event) {
var rect = container.getBoundingClientRect();
var x = event.clientX - rect.left;
var y = event.clientY - rect.top;
マーカーを (コンテナーに対して) このポイントに移動すると、[x, y]
クリックした場所に正確に表示されます。だから私はこれがうまくいっていることを知っています。次に、これらの座標のベクトルに逆変換行列を掛けます。
var vector = math.matrix([x, y, 0, 1]);
var result = math.multiply(inverseMatrixTransform, vector);
結果のベクトルの値[result.get([0]), result.get([1])]
に別のマーカー (画面要素に関連するもの) を移動すると、前のマーカーとほぼ同じ位置に移動しますが、正確ではありません。原点から遠ざかるほど誤差が大きくなり、右端と下端に向かってかなり悪くなります。
しかし、 と をチェックするoffsetX
とoffsetY
どうなるでしょうか。まあ、答えはブラウザに依存することがわかりました。
Firefox では、 で検索した座標offset*
もクリックした位置と一致しません。それらは私の計算したものとまったく同じではありませんが、数ピクセルだけ異なります。それらは、私の計算値と同じくらい実際にクリックされたポイントから離れています。
しかしChromeでは、で見つかった座標offset*
は完璧です。
ここにjsfiddleがあります。
私の計算で間違っていることはありますか?Chrome の結果を模倣する方法はありますが、offset*
プロパティはありませんか?