我有一个在原点和鼠标指针之间画一条线的SVG,我想做的是当按下shift时(event.shiftKey === true)使线条“快速”到最近45度坐标,基本上与你在photoshop中获得的行为相同。
我已经设法计算出两点之间的角度(所以我可以决定要捕捉哪个角度,如果需要可能使用IF / ELSE树)但是我不知道我是怎么回事根据新学位计算“结束”坐标。
我在这里设置了一个简化示例:https://jsbin.com/sohafekije/2/edit?html,js,output
我还拍了一张我试图重新创建的photoshop行为的照片(质量差,因为我不得不使用相机,因为我无法截图 - 抱歉)只是为了100%清晰:{{3 }}
http://i.imgur.com/Yo04uxY.jpg
基本上我正在尝试重新设置当你按住shift键时你在photoshop中获得的行为,但我的猜测是你需要很好地使用Maths来制定解决方案,而我不是!
非常感谢任何帮助:)
var app = document.getElementById('app'),
svg = SVG(app),
line = svg.polyline([]).fill('none').stroke({ width: 1 }),
start = [250,250],
end = null,
angleTxt = document.getElementById('angle'),
lineLengthTxt = document.getElementById('linelength');
line.marker('start', 10, 10, function(add) {
add.circle(10).fill('#f06')
})
// On mouse move, redraw the line
svg.on('mousemove', function(e){
end = [e.layerX, e.layerY];
line.plot([start, end]);
calcAngle();
});
function calcAngle() {
var deltaX = end[0] - start[0],
deltaY = end[1] - start[1],
rad = Math.atan2(deltaY, deltaX),
deg = rad * (180/Math.PI),
linelen = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
angleTxt.textContent = deg;
lineLengthTxt.textContent = linelen;
}
#app { border: 1px solid blue; width:100%; height:600px}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script type="text/javascript" src="https://rawgit.com/svgdotjs/svg.js/master/dist/svg.js"></script>
</head>
<body>
<div id="app"></div>
Angle: <span id="angle">-</span><br>
Line Length: <span id="linelength">-</span>
</body>
</html>
答案 0 :(得分:2)
我做到了!
如何使用
您计算新角度并使用cosinus将其应用于x值,将sin应用于y值。这里角度达到-PI到PI,步长为PI / 4;如果您想更改“var newAngle = ...”行中的步骤替换为其他数字。
它是如何运作的
首先,我考虑的事实是你需要8个角度位置,4个PI rad(cirlce是2PI rad)。所以你需要简化你的角度。
newAngle / Math.PI // value is between -1 and 1 (it's a double)
newAngle / Math.PI * 4 // value is between -4 and 4 (it's a double)
Math.round(newAngle / Math.PI * 4) // value is between -4 and 4 (but it's a integer now)
Math.round(newAngle / Math.PI * 4) / 4 // value is between -1 and 1 (with step of 0.25)
Math.round(newAngle / Math.PI * 4) / 4 * Math.PI // value is between -PI and PI with step of 0.25 * PI (PI/4)
现在你的新角度是正确的。 Cosinus返回角度的x值(查看维基百科的图形说明)和Sinus角度的y值。 通过将COSINUS / SINUS乘以您找到下一个点的长度。
function applyNewAngle() {
var deltaX = end[0] - start[0],
deltaY = end[1] - start[1],
dist = Math.sqrt(Math.pow(deltaX,2) + Math.pow(deltaY,2));
var newAngle = Math.atan2(deltaY, deltaX);
var shiftedAngle = Math.round(newAngle / Math.PI * 4) / 4 * Math.PI;
end = [start[0]+dist*Math.cos(shiftedAngle), start[1]+dist*Math.sin(shiftedAngle)];
}