2017-06-22 30 views
0

我正在創建一個編輯器。 我想在我的對象上的基本功能是旋轉/調整大小翻譯如何在調整大小期間讓我的光標與控制點同步?

我已經成功地做到了他們三人,但唯一的問題是我現在的鼠標位置不遵循控制點(該問題變得更壞下面沒有顯示其他控制點)..

您會在下面找到右側中間尺寸的示例,旋轉角度爲30度,沒有mouseY位置,請注意,當旋轉角度等於0時,鼠標完全遵循我的控制點。

是否有輕鬆的方式解決這個問題,我會走錯路嗎?

下面是jsfiddle鏈接,您可以在其中更改代碼中的旋轉角度以便自己查看JSiddle link。 (只需單擊並拖動黑色控制點來調整的對象)

//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是一個映射函數,用於將值v從一個範圍amin映射到amax,將另一個範圍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

哼thx再次,我喜歡整個重建過程不幸,這不能解決我的問題,因爲mouseY不存在。嘗試90度的角度,你會開始感覺到整個事情的真正問題。請讓我知道,如果你明白我的意思。 – JSmith

+0

我已經更新了答案。它現在(我相信)爲矩形的任何角度正確計算縮放比例。我沒有使用'getScreenCTM',而只是使用基本的三角函數重新計算鼠標移動的相關比例,這可能可以更優雅地使用,例如, 'getScreenCTM'或類似的東西。 –

+0

......不,還是一個問題......哼哼 –

相關問題