2017-06-12 6 views
1

このコードはコード内にあります。私が共有しようとしているのはちょっと複雑で密度が高いので、実際はコードを求めずアドバイスを求めています。回転した四角形をスケーリングして新しいコントロールポイントと中心を見つけよう

https://codepen.io/anon/pen/LLEedg?editors=0010

それは回転四角形を拡大縮小して、新しいスケールの矩形の頂点座標を見つけることについてです。

矩形を回転させると、その中心をビューポートの0,0に変換して回転します。その後私は元の場所に翻訳します。できます。

次に、transform-originを矩形の右下に移動するスケールを行います。ジャンプを避けるために、スケールの量と、回転動作がコントロールポイントに適用した平行移動を補正します。最後に、transform originを回転した矩形の左下に移動すると、私はジャンプを見ません。私は、新しいコントロールポイント(回転された座標ではなくスケーリングされたバージョン)で新しい境界ボックスを計算します。

その後、私は同じ方法で新しいtransform-originのスケールを行います。今回私は、新しいスケーリングされた回転していない新しいバウンディングボックスを取り、新しいスケーリングされたコントロールポイント座標を見つけるために同じメソッドを使って回転を行います。

私はそれらが画像の頂点に正確にあると思っていますが、ちょっと離れています。

おそらく、回転されたコントロールポイントの原点からのスケーリングであり、適切に補正されていない可能性があります。

コードペンのリンクで問題を再現するには、私は共有します。

最初に任意の量を左に回転します。

次に左上のハンドルを左にドラッグしてスケールします。

小さな黒い点は、緑色のハンドルの中央に正確に着く必要があります。

小さな黒いドットは、赤色の四角形が0,0で回転して、新しい制御点を計算するために、バック変換されます新しい境界ボックスであるストローク 、新しい制御点は、私は計算座標です。赤い塗りつぶしの青色のターゲットは、画像のtransform-originです。緑色の塗りつぶしの黄色のターゲットは、混乱しないように意図的に更新しないハンドルのtransform-originです。不透明度が大きい半径の大きい青い塗りつぶし円は、小さな黒い点から新しい計算中心です。

答えて

0

私は以下のようにこの問題を解決しました。私はより良い解決策を聞いてみたいと思います。

これは、回転操作とスケール操作の後に新しい頂点と中心を見つけることを扱います。

以下のすべてのコードブロックは、スケールイベントおよび回転イベントごとに評価する必要があります。

おそらくハンドルのドラッグイベントになります。

heightOfRectangleおよびWidthOfRectangleは、スケーリングされた値にする必要があります。

Ex。現在のスケールが1の場合3の場合はheightOfRectangleinitial rectangle's height*1.3

rotationAngleの合計角度をラジアンで適用する必要があります。

alphaは、Math.atan2(heightOfRectangle,WidthOfRectangle)です。

rは、Math.sqrt(Math.pow(WidthOfRectangle,2)+Math.pow(heightOfRectangle,2))/2 です。言い換えれば、矩形を作る2つの直角三角形によって共有される斜斜体。あなたは変換元の問題を克服し、原点ジャンプを変換防止異なるハンドルから 四角形を拡張することができ、アクティブハンドルはあなたが をドラッグして、変換の原点が配置されている場所の反対側にはハンドルであると仮定すると

。 たとえば、左上のハンドルからドラッグすると、原点は右下のハンドル位置に と表示されます。

activeHandleは、ドラッグするハンドルです。起源br bottomright用などのためにTOPLEFTため

tlo ..

tcは私は回転のためにドラッグ私のコードのための上部中央を意味します。

これは単にoriginイベントからの回転を意味します。

この回転前の最後のハンドル位置は、oldで始まる値にする必要があります。 この回転後、newで始まる値が新しいハンドル位置になります。

rxは、あなたはまだ解決される問題で、ここにペンを表示することができます回転Y

の略称 のx回転ryの略称です。

https://codepen.io/anon/pen/LLEedg?editors=0010

あなたはライン上updateControlPoints機能を表示することができます251

var cosRot = Math.cos(rotationAngle); 
var sinRot = Math.sin(rotationAngle); 

if (activeHandle === 'tc') { 

    var cosAMinusRot = Math.cos(alpha - rotationAngle); 
    var sinAMinusRot = Math.sin(alpha - rotationAngle); 
    var cosAPlusRot = Math.cos(alpha + rotationAngle); 
    var sinAPlusRot = Math.sin(alpha + rotationAngle); 
    var cos90APlusRot = Math.cos(Math.PI/2 - alpha + rotationAngle); 
    var sin90APlusRot = Math.sin(Math.PI/2 - alpha + rotationAngle); 
    var ox = old_ox; //means current ox 
    var oy = old_oy; //means current oy 
    //tl 
    var new_x = -r * cosAPlusRot + ox 
    var new_y = -r * sinAPlusRot + oy 
    new_tl.rx = new_x; 
    new_tl.ry = new_y; 
    //tr   

    new_x = +r * sin90APlusRot + ox 
    new_y = -r * cos90APlusRot + oy 
    new_tr.rx = new_x; 
    new_tr.ry = new_y; 
    //bl 
    new_x = -r * cosAMinusRot + ox 
    new_y = +r * sinAMinusRot + oy 
    new_bl.rx = new_x; 
    new_bl.ry = new_y; 
    //br 
    new_x = +r * cosAPlusRot + ox 
    new_y = +r * sinAPlusRot + oy 
    new_br.rx = new_x; 
    new_br.ry = new_y; 

} 

else if (activeHandle === 'tl') { 

    var cosAPlusRot = Math.cos(alpha + rotationAngle); 
    var sinAPlusRot = Math.sin(alpha + rotationAngle); 

    new_tl.rx = old_br.rx - 2 * r * cosAPlusRot; 
    new_tl.ry = old_br.ry - 2 * r * sinAPlusRot; 

    new_bl.rx = old_br.rx - WidthOfRectangle * cosRot; 
    new_bl.ry = old_br.ry - WidthOfRectangle * sinRot; 

    new_tr.rx = old_br.rx + HeightOfRectangle * sinRot; 
    new_tr.ry = old_br.ry - HeightOfRectangle * cosRot; 

    new_ox = old_br.rx - r * cosAPlusRot; 
    new_oy = old_br.ry - r * sinAPlusRot; 


} else if (activeHandle === 'tr') { 

    var cos180APlusRot = Math.cos(Math.PI - alpha + rotationAngle); 
    var sin180APlusRot = Math.sin(Math.PI - alpha + rotationAngle); 

    new_tl.rx = old_bl.rx + HeightOfRectangle * sinRot; 
    new_tl.ry = old_bl.ry - HeightOfRectangle * cosRot; 

    new_br.rx = old_bl.rx + WidthOfRectangle * cosRot; 
    new_br.ry = old_bl.ry + WidthOfRectangle * sinRot; 

    new_tr.rx = old_bl.rx - 2 * r * cos180APlusRot; 
    new_tr.ry = old_bl.ry - 2 * r * sin180APlusRot; 

    new_ox = old_bl.rx - r * cos180APlusRot; 
    new_oy = old_bl.ry - r * sin180APlusRot; 




} else if (activeHandle === 'bl') { 

    var cosAPlus90MinusRot = Math.cos(alpha + Math.PI/2 - rotationAngle); 
    var sinAPlus90MinusRot = Math.sin(alpha + Math.PI/2 - rotationAngle); 

    new_bl.rx = old_tr.rx - 2 * r * sinAPlus90MinusRot; 
    new_bl.ry = old_tr.ry - 2 * r * cosAPlus90MinusRot; 

    new_br.rx = old_tr.rx - HeightOfRectangle * sinRot; 
    new_br.ry = old_tr.ry + HeightOfRectangle * cosRot; 

    new_tl.rx = old_tr.rx - WidthOfRectangle * cosRot; 
    new_tl.ry = old_tr.ry - WidthOfRectangle * sinRot; 

    new_ox = old_tr.rx - r * sinAPlus90MinusRot; 
    new_oy = old_tr.ry - r * cosAPlus90MinusRot; 



} else if (activeHandle === 'br') { 

    var cosAPlusRot = Math.cos(alpha + rotationAngle); 
    var sinAPlusRot = Math.sin(alpha + rotationAngle); 

    new_bl.rx = old_tl.rx - HeightOfRectangle * sinRot; 
    new_bl.ry = old_tl.ry + HeightOfRectangle * cosRot; 

    new_br.rx = old_tl.rx + 2 * r * cosAPlusRot; 
    new_br.ry = old_tl.ry + 2 * r * sinAPlusRot; 

    new_tr.rx = old_tl.rx + WidthOfRectangle * cosRot; 
    new_tr.ry = old_tl.ry + WidthOfRectangle * sinRot; 

    new_ox = old_tl.rx + r * cosAPlusRot; 
    new_oy = old_tl.ry + r * sinAPlusRot; 



} 
関連する問題