2017-06-22 9 views
0

私はエディタを作成しています。 回転/サイズ変更を翻訳している私のオブジェクトの基本機能が欲しいです。サイズ変更中にカーソルをコントロールポイントと同期させるにはどうすればよいですか?

私はそれらのうち3つを行うことができたが、唯一の問題は私のマウスの位置は、(問題を以下に示していない他の制御点のためにも、最悪を取得)制御点に従っていません。..

なりました

右下のサイズが30度であり、マウスの位置が0でない場合の例を次に示します。回転角度が0の場合、マウスが完全に自分のコントロールポイントに完全に従うことに注意してください。

この問題を解決するには、私は間違った方法を行っていますか?

コードで回転角度を変更して自分で見ることができるjsfiddleリンクはJSiddle linkです。以下のコードは、それぞれのMouseMoveイベントに長方形の向きの方向にどのくらいのマウスの動きを算出し、代わりの

//convert value of range amin to amax to the range bmin to bmax; 
 
function imap(value, amin, amax, bmin, bmax) 
 
{ 
 
\t if ((amax - amin)) 
 
\t \t return (value - amin) * (bmax - bmin)/(amax - amin) + bmin; 
 
\t return (0); 
 
}; 
 

 
//get mouse coordinates from the SVG element 
 
function getMouse(el, e) 
 
{ 
 
    var pt = el.createSVGPoint(); 
 
\t pt.x = e.clientX; 
 
\t pt.y = e.clientY; 
 
\t var cursorpt = pt.matrixTransform(el.getScreenCTM().inverse()); 
 
\t return({x: cursorpt.x, y: cursorpt.y}) 
 
}; 
 

 
var controlPoint = document.getElementById("c"); //My control point element 
 

 
var mouseX; 
 
var mouseXClicked = 0; 
 
var scaleX = 1; 
 
var scaleY = 1; 
 
var scaleXClicked = 1; 
 
var control = false; // sets if resizeRightMiddle() should be executed 
 
var rectWidth = 100; //is normally tooken with a getBBox() function 
 
var scale = document.getElementById("scale"); 
 

 
function resizeRightMiddle() 
 
{ 
 
    //convert difference between original mouse X postion on click and actual X mouse position into a scale factor 
 
\t plusX = imap(mouseX - mouseXClicked, 0, rectWidth, 0, 1); 
 
    //add converted scale factor to the original x scale value 
 
\t resX = scaleXClicked + plusX; 
 
\t scale.setAttribute('transform', 'scale(' + resX + ',' + scaleY + ')'); 
 
\t scaleX = resX; 
 
} 
 

 
var svg = document.getElementById("main"); 
 
// save Scale and X mouse coordinate on click 
 
svg.addEventListener("mousedown", function(e){ 
 
\t var coord = getMouse(svg, e); 
 
\t mouseXClicked = coord.x; 
 
\t scaleXClicked = scaleX; 
 
}); 
 

 
svg.addEventListener("mousemove", function(e){ 
 
//get mouse coordinates 
 
\t var coord = getMouse(svg, e); 
 
\t mouseX = coord.x; 
 
// resize if control element has been clicked 
 
\t if (control) 
 
\t \t resizeRightMiddle(); 
 
}); 
 

 
// desactivate resize 
 
svg.addEventListener("mouseup", function(e){ 
 
\t control = false; 
 
}); 
 

 
//activate resize 
 
controlPoint.addEventListener("mousedown", function(){ 
 
\t control = true; 
 
});
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="300"> 
 
\t <g transform="translate(66, 56)"> 
 
\t \t <g id="rotate" transform-origin="center" transform="rotate(30)"> 
 
\t \t \t <g id="scale"> 
 
    \t \t \t <path fill="red" stroke="red" d="M 0 0 L 0 100 L 100 100 L 100 0Z" /> 
 
\t \t \t \t <rect id="c" fill="black" stroke="black" x=95 y=45 width=10 height=10 /> 
 
\t \t \t </g> 
 
\t \t </g> 
 
\t </g> 
 
</svg> 
 
</div>

+0

あなたのコードは、いくつかのより良い変数名と約オーバーおよび/またはその理由を見て少し簡単になります: 'imap'、' v'、 '何ですか...'、 'b ...'、 'RM'? –

+0

imapは、ある範囲のaminからamaxまでの値vを別の範囲bminからbmaxにマップするマッピング関数です。 RMは右の中間のサイズ変更機能です、形状をサイズ変更する主な機能です – JSmith

答えて

1

(ちょうどオブジェクトのサイズを変更するブラックコントロールポイントをクリックしてドラッグ) mousedownの始めから現在のmousemoveまで。その後、updatedRectWidthを更新し、それを使用して現在の所望のスケールを計算する。

var controlPoint = document.getElementById("c"); 
 
var control = false; 
 
var origRectWidth = 100; 
 
var scale = document.getElementById("scale"); 
 
var relevantMouseMoveDist = 0; 
 
var updatedRectWidth = origRectWidth; 
 
var mouseDownPt = {}; 
 
var rotateDiv = document.getElementById("rotate"); 
 
var rotateString = rotateDiv.getAttribute('transform'); 
 
var rectangleAngle = parseInt(rotateString.slice(rotateString.indexOf("(") + 1)) * Math.PI/180; // retrieve the angle from the DOM 
 
var relevantMouseMoveDist; 
 
var newMousePosn; 
 
var oldMousePosn; 
 

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

 
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 orientation 
 
    relevantMouseMoveDist = mouseMoveDist * Math.cos(angleDifference); 
 
    
 
    // resize the rectangle if necessary 
 
    if (control) resizeRightMiddle(); 
 
    
 
    } else { 
 
    
 
    // establish the mouse pos'n during the first mousemove event 
 
    newMousePosn = {x: e.clientX, y: e.clientY}; 
 
    } 
 
    
 
}); 
 

 
svg   .addEventListener("mouseup" , function(e){control = false;}); 
 
controlPoint.addEventListener("mousedown", function(e){control = true ;});
<div> 
 
<svg id="main" width="1000" height="300"> 
 
\t <g transform="translate(66, 56)"> 
 
\t \t <g id="rotate" transform-origin="center" transform="rotate(40)"> 
 
\t \t \t <g id="scale"> 
 
    \t \t \t <path fill="red" stroke="red" d="M 0 0 L 0 100 L 100 100 L 100 0Z" /> 
 
\t \t \t \t <rect id="c" fill="black" stroke="black" x=95 y=45 width=10 height=10 /> 
 
\t \t \t </g> 
 
\t \t </g> 
 
\t </g> 
 
</svg> 
 
</div>

+0

ハムスキー、私は残念ながら、残念ながらこれはマウスのように私の問題を解決しませんが存在しません。 90度の角度で試してみると、全体の本当の問題を感じ始めるでしょう。私が何を意味するかを私に知らせてください。 – JSmith

+0

私は答えを更新しました。今は(私は)矩形のどの角度に対してもスケーリングを正確に計算します。私は 'getScreenCTM'を使いませんでした。代わりに基本的な三角法を使ってマウスの動きの適切な部分を再計算しました。 'getScreenCTM'またはそれに類するもの。 –

+0

...いいえ、まだ問題ありません... –

関連する問題