2017-06-26 5 views
1

ここには元々this postから変更されたコードがあります。n-resizeの表示を正しくするにはどうしたらいいですか?

右中央、下中央、右下のコントロールポイントで矩形のサイズを変更すると、サイズ変更作業を行うために変換座標を変更する必要がないため、問題はありません。あなたが見ることができるように今私の問題は、私の四角形の上の中間(私の四角形の左の中央、左下と同じ...)で私のサイズを変更すると、回転角度が0と異なる場合は視覚的に私はサイズを変更します。

私は本当にそれを変更する方法を知らないので、どんな助けも高く評価されています。

注:入力フィールドの角度を0に変更すると、コードが正しく動作することがわかります。JSFiddle linkです。

var input = document.getElementById("rotate_input"); 
 
var rotate = document.getElementById("rotate"); 
 
var rightMiddle = document.getElementById("rm"); 
 
var topMiddle = document.getElementById("tm"); 
 
var translate = document.getElementById("trslt"); 
 
var scale = document.getElementById("scale"); 
 
var svg = document.getElementById("main"); 
 

 
var rotateString = rotate.getAttribute('transform'); 
 

 
var controlrm = false; 
 
var controltm = false; 
 

 
var origRectWidth = 100; 
 
var origRectHeight = 100; 
 
var updatedRectWidth = origRectWidth; 
 
var updatedRectHeight = origRectHeight; 
 

 
var xScale = 1; 
 
var yScale = 1; 
 

 
var translateX = 100; 
 
var translateY = 100; 
 

 
var relevantMouseMoveDist = 0; 
 

 
var rotateAnleDeg = 30; 
 
var rectangleAngle = parseInt(rotateString.slice(rotateString.indexOf("(") + 1)) * Math.PI/180; // retrieve the angle from the DOM 
 

 
var newMousePosn; 
 
var oldMousePosn; 
 

 
function resizeRightMiddle() 
 
{ 
 
    updatedRectWidth += relevantMouseMoveDistCos; 
 
    xScale = updatedRectWidth/origRectWidth; 
 
    scale.setAttribute('transform', 'scale(' + xScale + ',' + yScale + ')'); 
 
} 
 

 
function resizeTopMiddle() 
 
{ 
 
    updatedRectHeight -= relevantMouseMoveDistSin; 
 
    yScale = updatedRectHeight/origRectHeight; 
 
    //get the new Y position 
 
    translateY = translateY + relevantMouseMoveDistSin; 
 
    scale.setAttribute('transform', 'scale(' + xScale + ',' + yScale + ')'); 
 
    translate.setAttribute('transform', 'translate(' + translateX + ',' + translateY + ')'); 
 
} 
 

 
svg.addEventListener("mousemove", function(e){ 
 

 
    if (newMousePosn) { 
 
    
 
    // the former mouse pos'n 
 
    oldMousePosn = {x: newMousePosn.x, y: newMousePosn.y}; 
 
    
 
    // the new mouse pos'n 
 
    newMousePosn = {x: e.clientX, y: e.clientY}; 
 
    
 
    // the change in the mouse pos'n coordinates since the last move event 
 
    var deltaMouseMove = { 
 
     x: newMousePosn.x - oldMousePosn.x, 
 
     y: newMousePosn.y - oldMousePosn.y 
 
    }; 
 
    
 
    // the dir'n of this movement 
 
    var angleOfMouseMovement = Math.atan2(deltaMouseMove.y, deltaMouseMove.x); 
 
    
 
    // the absolute distance the mouse has moved 
 
    var mouseMoveDist = Math.sqrt(
 
     deltaMouseMove.x * deltaMouseMove.x + 
 
     deltaMouseMove.y * deltaMouseMove.y 
 
    ); 
 
     
 
    // the difference in direction between the mouse movement and orientation of the rectangle 
 
    var angleDifference = angleOfMouseMovement - rectangleAngle; 
 
    
 
    // the portion of the mouse movement that is in the direction of the rectangle's orientation 
 
    relevantMouseMoveDistCos = mouseMoveDist * Math.cos(angleDifference); 
 
    relevantMouseMoveDistSin = mouseMoveDist * Math.sin(angleDifference); 
 
    
 
    // resize the rectangle if necessary 
 
    if (controlrm) 
 
     resizeRightMiddle(); 
 
    else if (controltm) 
 
     resizeTopMiddle(); 
 
    } else { 
 
    
 
    // establish the mouse pos'n during the first mousemove event 
 
    newMousePosn = {x: e.clientX, y: e.clientY}; 
 
    } 
 
    
 
}); 
 

 
svg.addEventListener("mouseup" , function(e){ 
 
    controlrm = false; 
 
    controltm = false;}); 
 

 
rightMiddle.addEventListener("mousedown", function(e){controlrm = true ;}); 
 

 
topMiddle.addEventListener("mousedown", function(e){controltm = true ;}); 
 

 
// Code for changing the rectangle in the input 
 
input.addEventListener("change", function(){ 
 
    rotateAngleDeg = input.value; 
 
    rotate.setAttribute("transform", "rotate(" + rotateAngleDeg + ")"); 
 
    rectangleAngle = rotateAngleDeg * Math.PI/180; 
 
})
svg { 
 
    -webkit-touch-callout: none; 
 
    -webkit-user-select: none; 
 
    -khtml-user-select: none; 
 
    -moz-user-select: none; 
 
    -ms-user-select: none; 
 
    user-select: none; 
 
}
<svg id="main" width="1000" height="250"> 
 
<g id= "trslt" transform="translate(100, 100)"> 
 
    <g id="rotate" transform-origin="center" transform="rotate(30)"> 
 
    <g id="scale"> 
 
    <path fill="red" stroke="red" d="M 0 0 L 0 100 L 100 100 L 100 0Z" /> 
 
    <rect id="rm" fill="black" stroke="black" x=95 y=45 width=10 height=10 /> 
 
    <rect id="tm" fill="white" stroke="black" x=45 y=-5 width=10 height=10 /> 
 
    </g> 
 
    </g> 
 
</g> 
 
</svg> 
 
<input id="rotate_input" type="text" placeholder="Change Angle"/>

答えて

2

あり、それにはかなりだとかなり難しいステップを説明するために、本質的に:

  • svg内の後RotateTranslateを移動しました。これにより、回転の影響を受ける方向を考慮する必要なしにオブジェクトのサイズを変更するのが容易になりました。
  • 私は回転を適用するために3つの値を使用しましたtransform="rotate(0 0 0)"。 2番目の2つは回転中心を与える。
  • ボックスの寸法を0の中央に変更しました。厳密には必要ではありませんが、私はそのように数学について考えることをお勧めしました。

私はパターンに従うためにあなたとそれを残しておきます、側面と一つのコーナーを実装しました - 左上のためにそれだけでトップからコードと左からコードをつかみましたと私は回転は常にボックスの現在の中心点を中心に発生しませんので、それは私はあなたが修正を見てみたいと思う推測何かで見右上以内すでに

をやったようにそれらを組み合わせます。

(以下スタックスニペットと同じ)外部デモ:https://jsfiddle.net/bcjopdqn/2/

var input = document.getElementById("rotate_input"); 
 
var rotate = document.getElementById("rotate"); 
 
var rightMiddle = document.getElementById("rm"); 
 
var leftMiddle = document.getElementById("lm"); 
 
var topMiddle = document.getElementById("tm"); 
 
var bottomMiddle = document.getElementById("bm"); 
 
var topRight = document.getElementById("tr"); 
 

 
var translate = document.getElementById("trslt"); 
 
var scale = document.getElementById("scale"); 
 

 
var rotateString = rotate.getAttribute('transform'); 
 

 
var controlrm = false; 
 
var controllm = false; 
 
var controltm = false; 
 
var controlbm = false; 
 
var controltr = false; 
 

 
var origRectWidth = 100; 
 
var origRectHeight = 100; 
 
var updatedRectWidth = origRectWidth; 
 
var updatedRectHeight = origRectHeight; 
 

 
var xScale = 1; 
 
var yScale = 1; 
 

 
var translateX = 100; 
 
var translateY = 100; 
 

 
var relevantMouseMoveDist = 0; 
 
var relevantMouseMoveDistXCos, relevantMouseMoveDistXSin; 
 
var relevantMouseMoveDistYCos, relevantMouseMoveDistYSin; 
 

 
var rotateAngleDeg = 0; 
 
var rectangleAngle = parseInt(rotateString.slice(rotateString.indexOf("(") + 1)) * Math.PI/180; // retrieve the angle from the DOM 
 

 
var newMousePosn; 
 
var oldMousePosn; 
 

 
function resizeLeftMiddle() { 
 
    updatedRectWidth -= relevantMouseMoveDistXCos + relevantMouseMoveDistXSin; 
 
    translateX += relevantMouseMoveDistXCos/2 + relevantMouseMoveDistXSin/2; 
 
    xScale = updatedRectWidth/origRectWidth; 
 
    scale.setAttribute('transform', 'scale(' + xScale + ',' + yScale + ')'); 
 
    translate.setAttribute('transform', 'translate(' + translateX + ',' + translateY + ')'); 
 
} 
 

 
function resizeRightMiddle() { 
 
    updatedRectWidth += relevantMouseMoveDistXCos + relevantMouseMoveDistXSin; 
 
    translateX += relevantMouseMoveDistXCos/2 + relevantMouseMoveDistXSin/2; 
 
    xScale = updatedRectWidth/origRectWidth; 
 
    scale.setAttribute('transform', 'scale(' + xScale + ',' + yScale + ')'); 
 
    translate.setAttribute('transform', 'translate(' + translateX + ',' + translateY + ')'); 
 
} 
 

 
function resizeTopMiddle() { 
 
    updatedRectHeight -= relevantMouseMoveDistYCos + relevantMouseMoveDistYSin; 
 
    translateY += relevantMouseMoveDistYCos/2 + relevantMouseMoveDistYSin/2; 
 
    yScale = updatedRectHeight/origRectHeight; 
 
    scale.setAttribute('transform', 'scale(' + xScale + ',' + yScale + ')'); 
 
    translate.setAttribute('transform', 'translate(' + translateX + ',' + translateY + ')'); 
 
} 
 

 
function resizeBottomMiddle() { 
 
    updatedRectHeight += relevantMouseMoveDistYCos + relevantMouseMoveDistYSin; 
 
    translateY += relevantMouseMoveDistYCos/2 + relevantMouseMoveDistYSin/2; 
 
    yScale = updatedRectHeight/origRectHeight; 
 
    scale.setAttribute('transform', 'scale(' + xScale + ',' + yScale + ')'); 
 
    translate.setAttribute('transform', 'translate(' + translateX + ',' + translateY + ')'); 
 
} 
 

 
function resizeTopRight() { 
 
    updatedRectWidth += relevantMouseMoveDistXCos + relevantMouseMoveDistXSin; 
 
    updatedRectHeight -= relevantMouseMoveDistYCos + relevantMouseMoveDistYSin; 
 
    translateX += relevantMouseMoveDistXCos/2 + relevantMouseMoveDistXSin/2; 
 
    translateY += relevantMouseMoveDistYCos/2 + relevantMouseMoveDistYSin/2; 
 
    xScale = updatedRectWidth/origRectWidth; 
 
    yScale = updatedRectHeight/origRectHeight; 
 
    scale.setAttribute('transform', 'scale(' + xScale + ',' + yScale + ')'); 
 
    translate.setAttribute('transform', 'translate(' + translateX + ',' + translateY + ')'); 
 
} 
 

 
var svg = document.getElementById("main"); 
 

 
svg.addEventListener("mousemove", function(e) { 
 

 
    if (newMousePosn) { 
 

 
    // the former mouse pos'n 
 
    oldMousePosn = { 
 
     x: newMousePosn.x, 
 
     y: newMousePosn.y 
 
    }; 
 

 
    // the new mouse pos'n 
 
    newMousePosn = { 
 
     x: e.clientX, 
 
     y: e.clientY 
 
    }; 
 

 
    // the change in the mouse pos'n coordinates since the last move event 
 
    var deltaMouseMove = { 
 
     x: newMousePosn.x - oldMousePosn.x, 
 
     y: newMousePosn.y - oldMousePosn.y 
 
    }; 
 

 
    // the dir'n of this movement 
 
    //var angleOfMouseMovement = Math.atan2(deltaMouseMove.y, deltaMouseMove.x); 
 

 
    // the absolute distance the mouse has moved 
 
    var mouseMoveDist = Math.sqrt(
 
     deltaMouseMove.x * deltaMouseMove.x + 
 
     deltaMouseMove.y * deltaMouseMove.y 
 
    ); 
 

 
    // the difference in direction between the mouse movement and orientation of the rectangle 
 
    //var angleDifference = angleOfMouseMovement - rectangleAngle; 
 

 
    // the portion of the mouse movement that is in the direction of the rectangle's +X and +Y orientation 
 
    relevantMouseMoveDistXCos = deltaMouseMove.x * Math.cos(rectangleAngle); 
 
    relevantMouseMoveDistXSin = deltaMouseMove.y * Math.sin(rectangleAngle); 
 

 
    relevantMouseMoveDistYCos = deltaMouseMove.x * Math.cos(rectangleAngle + Math.PI/2); 
 
    relevantMouseMoveDistYSin = deltaMouseMove.y * Math.sin(rectangleAngle + Math.PI/2); 
 

 
    // resize the rectangle if necessary 
 
    if (controlrm) 
 
     resizeRightMiddle(); 
 
    else if (controllm) 
 
     resizeLeftMiddle(); 
 
    else if (controltm) 
 
     resizeTopMiddle(); 
 
    else if (controlbm) 
 
     resizeBottomMiddle(); 
 
    else if (controltr) 
 
     resizeTopRight(); 
 
    } else { 
 

 
    // establish the mouse pos'n during the first mousemove event 
 
    newMousePosn = { 
 
     x: e.clientX, 
 
     y: e.clientY 
 
    }; 
 
    } 
 

 
}); 
 

 
svg.addEventListener("mouseup", function(e) { 
 
    controlrm = false; 
 
    controllm = false; 
 
    controltm = false; 
 
    controlbm = false; 
 
    controltr = false; 
 
}); 
 

 
rightMiddle.addEventListener("mousedown", function(e) { 
 
    controlrm = true; 
 
}); 
 
leftMiddle.addEventListener("mousedown", function(e) { 
 
    controllm = true; 
 
}); 
 
topMiddle.addEventListener("mousedown", function(e) { 
 
    controltm = true; 
 
}); 
 
bottomMiddle.addEventListener("mousedown", function(e) { 
 
    controlbm = true; 
 
}); 
 
topRight.addEventListener("mousedown", function(e) { 
 
    controltr = true; 
 
}); 
 

 
// Code for changing the rectangle in the input 
 
input.addEventListener("change", function() { 
 

 
    rotateAngleDeg = input.value; 
 

 
    var translation = (translateX + " " + translateY); 
 
    var rotation = "rotate(" + rotateAngleDeg + " " + translation + ")"; 
 

 
    rotate.setAttribute("transform", rotation); 
 
    //console.log(rotation); 
 

 
    rectangleAngle = rotateAngleDeg * Math.PI/180; 
 
})
svg { 
 
    -webkit-touch-callout: none; 
 
    -webkit-user-select: none; 
 
    -khtml-user-select: none; 
 
    -moz-user-select: none; 
 
    -ms-user-select: none; 
 
    user-select: none; 
 
}
<div> 
 
    <svg id="main" width="1000" height="250"> 
 
    <g id="rotate" transform-origin="0 0" transform="rotate(0 0 0)"> 
 
     <g id="trslt" transform="translate(100, 100)"> 
 
     <g id="scale"> 
 
      <path fill="red" stroke="red" d="M -50 -50 L -50 50 L 50 50 L 50 -50Z" /> 
 
      <rect id="rm" fill="black" stroke="black" x=45 y=-5 width=10 height=10 /> 
 
      <rect id="lm" fill="yellow" stroke="black" x=-55 y=-5 width=10 height=10 /> 
 
      <rect id="tm" fill="white" stroke="black" x=-5 y=-55 width=10 height=10 /> 
 
      <rect id="bm" fill="orange" stroke="black" x=-5 y=45 width=10 height=10 /> 
 
      <rect id="tr" fill="blue" stroke="black" x=45 y=-55 width=10 height=10 /> 
 
     </g> 
 
     </g> 
 
    </g> 
 
    </svg> 
 
</div> 
 
<input id="rotate_input" type="text" placeholder="Change Angle" />

+0

答えをありがとうが、私は回転と反転を反転させることなく解決策を見つけました。 – JSmith

+0

作業には数時間かかりましたので、必要がなくても私の答えを受け入れていただき、ありがとうございます。あなたが最後に結果を得てうれしい –

+0

問題はない、私は私の質問のすべての制約に言及していない。オブジェクトをドラッグしたときに回転を反転して平行移動すると、すべての座標が回転するので、それは別の問題です。しかし、あなたの時間のために多くのありがとう。 – JSmith

1

ない100%の作業が、これはうまくいけば、あなたは正しい方向にあなたを簡素化し、ポイントに役立つはずです。 SVG変換行列を使用するこの関数をチェックアウトします。
https://codepen.io/anon/pen/xrpPBy

あなたはほどあなたの関数を更新することができます。

function resizeTopMiddle() 
{ 
    updatedRectHeight -= relevantMouseMoveDistSin; 
    yScale = updatedRectHeight/origRectHeight; 

    generalTX(xScale, yScale, rotateAnleDeg) 
} 

をここにあなたのユースケースと例です。 https://codepen.io/RTakes/pen/xrpLEe

お役に立てば幸いです。

+0

私は、このヘルプのためのルックTHXは、制御点の残りのために実装することが容易である必要がありますか? – JSmith

+0

私はあなたがしたことを理解していると思います、それは元の質問ではありませんでした。私はコントロールポイントを反転させたくありません。私はすでにボトム・ミドル・コントロール・ポイントを簡単にプログラムしました。そして、それは私の四角形の位置(翻訳)を変更するので面白いトップミドルです。とにかくThx – JSmith

+0

申し訳ありませんが、私は完全に質問を理解していませんでした。私は例と答えを更新しています。 – RickTakes

関連する問題