4

HTML5 では、キャンバス要素に変換機能を実装したいので、ユーザーはキャンバス要素をtranslate(移動)、scale(ズームイン/アウト)できrotateます。このような各変換は、異なる変換起点で実行できます。

最初の変換は簡単です:

function transform(el, value, origin) {
  el.style.Transform = value;
  el.style.MozTransform = value;
  el.style.msTransform = value;
  el.style.OTransform = value;
  el.style.webkitTransform = value;
  el.style.TransformOrigin = origin;
  el.style.MozTransformOrigin = origin;
  el.style.msTransformOrigin = origin;
  el.style.OTransformOrigin = origin;
  el.style.webkitTransformOrigin = origin;
}

transform(myCanvas, 'translate('+ dx +'px, ' + dy + 'px) ' +
                    'scale(' + zoom + ', ' + zoom + ') ' +
                    'rotate(' + angle + 'deg)',
                    cx + 'px ' + cy + 'px');

ユーザーは一度にすべてではなく、要素を移動、ズーム、または回転するため、変換の一部のパラメーターはデフォルトのままになります(dx = 0、dy = 0、ズーム = 1、角度 = 0)

このような変換の後、ユーザーが別の変換 (および別の変換など) を行いたい場合、(dx1, dy1, zoom1, angle1, cx1, cy1)(dx2, dy2, zoom2, angle2 , cx2) をどのように組み合わせることができますか? 、cy2)後で新しい変換パラメーターと組み合わせることができる最終値を取得するには? transform異なる可能性があるため、パラメーターに別の変換を追加することはできませんtranform-origin。変換を異なる変換原点と組み合わせる方法はありますか?

4

2 に答える 2

9

行列計算を学ぶ必要はありません。CSS Transform 仕様によると

  1. 恒等行列から始めます。
  2. 'transform-origin' の計算された X、Y、および Z 値によって移動します。
  3. 「transform」プロパティの各変換関数を順番に乗算します
  4. 「transform-origin」の計算された X、Y、および Z の値を否定して変換します</li>

つまり、transform-origin: A; transform: Bと同じtransform: translate(-A) B translate(A)です。(変換は右から左に適用されるため、最初に実行したいことが最後に行われます。)

したがって、上記のルールを使用して排除するtransform-originと、連結できる単純な変換が得られます。

例:

  1. transform-origin: 5px 5px; transform: translate(10px, 40px)
  2. transform-origin: 25px 30px; transform: scale(2)
  3. transform-origin: 10px 10px; transform: rotate(30deg)

になる

  1. transform: translate(-5px, -5px) translate(10px, 40px) translate(5px, 5px)
  2. transform: translate(-25px, -30px) scale(2) translate(25px, 30px)
  3. transform: translate(-10px, -10px) rotate(30deg) translate(10px, 10px)

それらはすべて起源に同意しているため(つまり、起源がない)、これらを組み合わせることができます。

transform: translate(-5px, -5px) translate(10px, 40px) translate(5px, 5px) translate(-25px, -30px) scale(2) translate(25px, 30px) translate(-10px, -10px) rotate(30deg) translate(10px, 10px)

もちろん、必要に応じて連続翻訳を折りたたむこともできます

transform: translate(-15px, 10px) scale(2) translate(15px, 20px) rotate(30deg) translate(10px, 10px)

または、数学の教科書を調べて、最終的な変換行列を計算することもできます。

編集: 変換は右から左に適用されます。

于 2012-07-14T22:31:46.860 に答える
1

マトリックス変換に対処する必要があります。

すべての線形操作は、平面の点に適用できる 3x3 行列と 3x1 ベクトルで表すことができます。pが点、Mが行列、qが他のベクトルの場合、すべての線形変換はMp + qとして表すことができます。

2 次元の点がある場合、そのベクトルは [ x; y; 1 ] (垂直ベクトル) ですが、行列はいくつかの形式にすることができます。

翻訳の場合、行列は単なる恒等行列です。ベクトルqは並進ベクトルです。

スケーリングの場合、Mは次のようになります

    [a 0 0]
M = [0 b 0]
    [0 0 1]

ここで、abはそれぞれxyの倍率です。ベクトルqは null です。

回転の場合、たとえば角度aを取得すると、

    [cos(a) -sin(a) 0]
M = [sin(a)  cos(a) 0]
    [  0       0    1]

qは再び null です。

歪ませるための行列もあります。したがって、3 つの連続した変換を適用する必要がある場合は、この種の線形変換を適用する必要があります。あなたの問題は、原点にも対処しなければならないことです。そのため、Mを適用し、 qを追加してからoを追加するよりも、 pからベクトルoを減算する必要があります。

これらの変換 ( M1, q1, o1 ) および ( M2, q2, o2 ) があるとします。あなたが得る最初のものを適用するとき

p1 = M1 * (p - o1) + q1 + o1

次に、2 番目の変換を適用する必要があります。

p2 = M2 * (p1 - o2) + q2 + o2

最終的に次のようになります。

p2 = M2 * (M1 * (p - o1) + q1 + o1 - o2) + q2 + o2

そして、最終的な 3 番目 ( M3, q3, o3 ) についても同様です。

混乱?みたいですね。しかし、行列がどのように見えるかを知っていれば、物事は少し単純化できます。

次に、計算を行い、それを に適用しますtransform: matrix(a, b, c, d, tx, ty)

于 2012-07-14T22:15:05.083 に答える