javascript - 如何在一组方向上移动 SVG 中的线
问题描述
我有一个由 4 个线条形状组成的矩形。我希望能够通过拖动它的 4 个边之一来调整它的大小,但它需要保持矩形形状,我将尝试说明如下:
线条ab
, bc
, cd
,da
是单独的线条形状。在这个例子中,通过用鼠标拖动,我需要移动线条cd
,但它需要与其他线条保持矩形形状(也需要对所有线条起作用,cd
只是示例)。到目前为止,我有一个用于拖动线的代码:
function moveLine(previousCoo, x1, y1, x2, y2){ //following example above, x1 and y1 are point d and x2, y2 are point c
if(document.getElementById('Line')){
document.removeChild(document.getElementById('Line'));
}
var myLine = document.createElementNS("http://www.w3.org/2000/svg", "line");
myLine.setAttributeNS(null, "id", "Line");
myLine.setAttributeNS(null, "x1", x1);
myLine.setAttributeNS(null, "y1", y1);
myLine.setAttributeNS(null, "x2", x2);
myLine.setAttributeNS(null, "y2", y2);
myLine.setAttributeNS(null, "stroke", "green");
myLine.setAttributeNS(null, "stroke-width", 3);
$(myLine).mousemove(function (e) { //on mouse move, mousedown is already determined from another function
var coo = getCoordinates(e.pageX, e.pageY); //function for getting current mouse coordinates
var dCoo = [coo[0] - previousCoo[0], coo[1] - previousCoo[1]]; //calculate how much the mouse was moved
x1 += dCoo[0];
y1 += dCoo[1];
x2 += dCoo[0];
y2 += dCoo[1];
moveLine(coo, x1, y1, x2, y2);
}.bind(this));
$(myLine).mouseup(function (e) {
finish();
}.bind(this));
document.appendChild(myLine);
}
这仅适用于移动线,但我需要它仅沿上图所示的方向移动。我试着玩鼻窦、鼻窦和什么没用但没有用的东西。有人可以指出我正确的方向吗?谢谢!
解决方案
我正在使用 Robert Longson 的想法来旋转坐标系。
我会这样做:
矩形和线条围绕 [0,0] 点绘制,并且它们所在的组被旋转。这些线也有一个h
水平线和v
垂直线的类。或者,您可以检查是否 x1 == x2 用于垂直线或 y1 == y2 用于水平线,而不是分类。
当您拖动线条时,您会重置水平线的y1
,属性和垂直线的,属性。y2
x1
x2
该功能oMousePosSVG
正在检测 svg 画布上的鼠标位置。
let lines = Array.from(document.querySelectorAll("#greenLines line"));
let dragging = false;
let theclass = "";
let theLine = null;
let m = {}
lines.forEach((l,i) =>{
l.addEventListener("mousedown",()=>{
dragging = i+1;
l.style.stroke = "red"
theclass = l.getAttribute("class")
theLine = lines[dragging - 1];
})
})
svg.addEventListener("mousemove",(e)=>{
if(dragging){
m = oMousePosSVG(e)
if(theclass == "h"){
theLine.setAttributeNS(null,"y1",m.y);
theLine.setAttributeNS(null,"y2",m.y);
}
if(theclass == "v"){
theLine.setAttributeNS(null,"x1",m.x);
theLine.setAttributeNS(null,"x2",m.x);
}
}
})
svg.addEventListener("mouseup",()=>{
lines[dragging - 1].style.stroke = "green";
dragging = false;
})
function oMousePosSVG(e) {
var p = svg.createSVGPoint();
p.x = e.clientX;
p.y = e.clientY;
var ctm = svg.getScreenCTM().inverse();
var p = p.matrixTransform(ctm);
return p;
}
svg{border:1px solid}
#greenLines line{stroke:green; stroke-width:5px;stroke-linecap:round}
<svg id="svg" viewBox="-100 -100 200 200" >
<g transform="rotate(25)">
<polygon id="poly" points="-50,-30 50,-30 50,30 -50,30 -50,30"/>
<g id="greenLines">
<line id="ab" class="h" x1="-50" y1="30" x2="50" y2="30" />
<line id="bc" class="v" x1="50" y1="30" x2="50" y2="-30" />
<line id="cd" class="h" x1="50" y1="-30" x2="-50" y2="-30" />
<line id="da" class="v" x1="-50" y1="-30" x2="-50" y2="30" />
</g>
</g>
</svg>
推荐阅读
- javascript - React jsx 版本的 html(使用不同的标签,但相同的属性和逻辑)不会触发 jquery on('change') 方法
- css - 自定义图标集未在 Safari 中显示
- javascript - 如何使用输入类型=“文件”和 axios 将图像“重新上传”到服务器?
- python - 如何获取日期以在 Django 中以表单形式输出?
- java - 用java调试字符串反转
- javascript - 按 ID 获取元素返回 null
- ios - “访问钥匙串时出错”
- python - 在 Pandas 中,如何使用 Regex 将人类可读的时间格式分解为不同的单位,例如天、小时、分钟和秒?
- jquery - 表中的总类安装
- android - 我正在尝试使用 GridLayoutManager 和自定义适配器创建 RecyclerView