2017-06-26 35 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

有相當多的把它和相當難以解釋的步驟,但基本上是:

  • 感動TranslateRotatesvg內。這樣可以更輕鬆地調整對象的大小,而無需考慮旋轉會影響的方向。
  • 我使用了3個值來應用旋轉transform="rotate(0 0 0)"。後面兩個給出了輪換的中心。
  • 將箱子尺寸更改爲以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