SVG - 调整以一定角度放置的矩形的大小
所有,
我的应用程序中有一个 SVG 矩形,可以通过拖动矩形两侧的结束栏(左和右)来水平拉伸它。矩形可以
(1) 调整大小(通过如上所述拉伸)、
(2) 拖动、
(3) 和拖动。旋转。
一切工作正常,但是,一个奇怪的经历是,当我将矩形旋转到接近 90 度时,&然后尝试调整矩形的大小,它从矩形的相对边框而不是原始边框开始拉伸。 (这是图片):
当我使用旋转功能时,左右似乎变得混乱。
这是修改后的 HTML、JS 和SVG:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<!-- <script type="text/javascript" src="CPolyline.js">
</script>-->
</head>
<body>
<object id="oo" data="rect2.svg" style="position:fixed;width: 800px;height:800px;bottom:-100px;right: 375px;">
</object>
path: <input type="button" id="path" onclick="X()">
path2: <input type="button" id="path2" onclick="Y()">
<input type="button" value="Rotate" onclick="Rotate1()">
<script type="text/javascript">
var ob=document.getElementById("oo")
var svgDoc=null;
var svgRoot=null;
var MyGroupObjectsObj = null;
var svgNS = "http://www.w3.org/2000/svg";
var dragTarget = null;
var rectTemplate = null;
var grabPoint = null;
var clientPoint = null;
var rectX = null;
var rectY = null;
var rectWidth = null;
var rectHeight = null;
var arr=new Array();
var resizingLeft = false;
var resizingRight = false;
var rectrot=null
ob.addEventListener("load", function(){
svgDoc=ob.contentDocument;
svgRoot=svgDoc.documentElement;
grabPoint = svgRoot.createSVGPoint();
clientPoint = svgRoot.createSVGPoint();
rectTemplate = svgDoc.getElementById('rectTemplate')
rectrot=svgDoc.getElementById("rect1")
}, false)
var angel=0
function Rotate1()
{
angel=angel+10
//alert(rectrot)
var c=rectTemplate.getAttribute("transform");
var widt=Number(rectTemplate.getAttribute("width"))/2;
var hie=Number(rectTemplate.getAttribute("height"))/2
var tran=c.match(/[\d\.]+/g);
var newxpo=Number(tran[0])+widt;
var newypo=Number(tran[1])+hie;
var r=Math.tan((newxpo)/(newypo))
rectTemplate.parentNode.setAttribute("transform","translate("+newxpo+" "+newypo+")"+"rotate("+angel+") translate("+(newxpo*-1)+" "+(newypo*-1)+")");
}
function MouseDown(evt)
{
var targetElement = evt.target;
var checkForResizeAttempt = false;
if (targetElement == rectTemplate)
{
//arr.push(cir ,cir1,rectTemplate)
dragTarget = targetElement;
checkForResizeAttempt = true;
var transMatrix = dragTarget.getCTM();
grabPoint.x = evt.clientX - Number(transMatrix.e);
grabPoint.y = evt.clientY - Number(transMatrix.f);
}
var transMatrix = dragTarget.getCTM();
//var transMatrix = dragTarget.getCTM().inverse();
grabPoint.x = evt.clientX - Number(transMatrix.e);
grabPoint.y = evt.clientY - Number(transMatrix.f);
if (window.console) console.log(grabPoint.x + " " + grabPoint.y);
if (window.console) console.log(evt.clientX + " " + evt.clientY);
if (checkForResizeAttempt)
{
clientPoint.x = evt.clientX;
clientPoint.y = evt.clientY;
rectX = Number(dragTarget.getAttributeNS(null, "x"));
rectY = Number(dragTarget.getAttributeNS(null, "y"));
rectWidth = Number(dragTarget.getAttributeNS(null, "width"));
rectHeight = Number(dragTarget.getAttributeNS(null, "height"));
if ((grabPoint.x - rectX) < 10)
{
resizingLeft = true;
}
else if (((rectX + rectWidth) - grabPoint.x) < 10)
{
resizingRight = true;
}
if (resizingLeft || resizingRight)
{
dragTarget.setAttributeNS(null,"stroke","green");
}
else
{
dragTarget.setAttributeNS(null,"stroke","black");
}
}
}
function MouseMove(evt)
{
evt.stopPropagation();
if (dragTarget == null)
{
return;
}
if (resizingLeft)
{
if (window.console) console.log(evt.clientX + " " + evt.clientY);
deltaX = (clientPoint.x - evt.clientX);
if (window.console) console.log("deltaX = " + deltaX);
dragTarget.setAttributeNS(null,"width",rectWidth + deltaX);
dragTarget.setAttributeNS(null,"x",rectX - deltaX);
}
else if (resizingRight)
{
deltaX = (clientPoint.x - evt.clientX);
if (window.console) console.log("rectWidth = " + rectWidth + " deltaX = " + deltaX);
dragTarget.setAttributeNS(null,"width",rectWidth - deltaX);
}
else
{
var newXX = evt.clientX-grabPoint.x;
var newYX = evt.clientY-grabPoint.y;
dragTarget.setAttributeNS(null,'transform','translate(' + newXX + ',' + newYX + ')');
}
}
function MouseUp(evt)
{
evt.stopPropagation();
if (dragTarget == null)
{
return;
}
resizingLeft = false;
resizingRight = false;
resizingTop = false;
resizingBottom = false;
// var transMatrix = dragTarget.getCTM().inverse();
dragTarget.setAttributeNS(null,"stroke","blue");
dragTarget = null;
}
</script>
</body>
</html>
--
=======SVG ====
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" width="612px" height="792px" xml:space="preserve"
onmousedown="ecmascript:top.MouseDown(evt)"
onmousemove="ecmascript:top.MouseMove(evt)"
onmouseup="ecmascript:top.MouseUp(evt)">
<g id="rect1">
<rect id="rectTemplate" x="0" y="0" stroke="blue" width="100" height="30" />
</g>
All,
I have a SVG rectangle in my application which can be stretched horizontally by dragging the end bar (left & right) on either side of the rectangle. The rectangle can be
(1) resized (by stretching as per above),
(2)dragged,
(3)& rotated.
Everything works fine, however, one strange experience is that when I rotate the rectangle to a degree close to 90, & then try to resize the rectangle, it starts stretching from the opposite border of the rectangle instead of the original borders. (here is the image):
It appears to be getting confused between left and right when I use the rotate function.
Here is the revised HTML, JS & SVG:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<!-- <script type="text/javascript" src="CPolyline.js">
</script>-->
</head>
<body>
<object id="oo" data="rect2.svg" style="position:fixed;width: 800px;height:800px;bottom:-100px;right: 375px;">
</object>
path: <input type="button" id="path" onclick="X()">
path2: <input type="button" id="path2" onclick="Y()">
<input type="button" value="Rotate" onclick="Rotate1()">
<script type="text/javascript">
var ob=document.getElementById("oo")
var svgDoc=null;
var svgRoot=null;
var MyGroupObjectsObj = null;
var svgNS = "http://www.w3.org/2000/svg";
var dragTarget = null;
var rectTemplate = null;
var grabPoint = null;
var clientPoint = null;
var rectX = null;
var rectY = null;
var rectWidth = null;
var rectHeight = null;
var arr=new Array();
var resizingLeft = false;
var resizingRight = false;
var rectrot=null
ob.addEventListener("load", function(){
svgDoc=ob.contentDocument;
svgRoot=svgDoc.documentElement;
grabPoint = svgRoot.createSVGPoint();
clientPoint = svgRoot.createSVGPoint();
rectTemplate = svgDoc.getElementById('rectTemplate')
rectrot=svgDoc.getElementById("rect1")
}, false)
var angel=0
function Rotate1()
{
angel=angel+10
//alert(rectrot)
var c=rectTemplate.getAttribute("transform");
var widt=Number(rectTemplate.getAttribute("width"))/2;
var hie=Number(rectTemplate.getAttribute("height"))/2
var tran=c.match(/[\d\.]+/g);
var newxpo=Number(tran[0])+widt;
var newypo=Number(tran[1])+hie;
var r=Math.tan((newxpo)/(newypo))
rectTemplate.parentNode.setAttribute("transform","translate("+newxpo+" "+newypo+")"+"rotate("+angel+") translate("+(newxpo*-1)+" "+(newypo*-1)+")");
}
function MouseDown(evt)
{
var targetElement = evt.target;
var checkForResizeAttempt = false;
if (targetElement == rectTemplate)
{
//arr.push(cir ,cir1,rectTemplate)
dragTarget = targetElement;
checkForResizeAttempt = true;
var transMatrix = dragTarget.getCTM();
grabPoint.x = evt.clientX - Number(transMatrix.e);
grabPoint.y = evt.clientY - Number(transMatrix.f);
}
var transMatrix = dragTarget.getCTM();
//var transMatrix = dragTarget.getCTM().inverse();
grabPoint.x = evt.clientX - Number(transMatrix.e);
grabPoint.y = evt.clientY - Number(transMatrix.f);
if (window.console) console.log(grabPoint.x + " " + grabPoint.y);
if (window.console) console.log(evt.clientX + " " + evt.clientY);
if (checkForResizeAttempt)
{
clientPoint.x = evt.clientX;
clientPoint.y = evt.clientY;
rectX = Number(dragTarget.getAttributeNS(null, "x"));
rectY = Number(dragTarget.getAttributeNS(null, "y"));
rectWidth = Number(dragTarget.getAttributeNS(null, "width"));
rectHeight = Number(dragTarget.getAttributeNS(null, "height"));
if ((grabPoint.x - rectX) < 10)
{
resizingLeft = true;
}
else if (((rectX + rectWidth) - grabPoint.x) < 10)
{
resizingRight = true;
}
if (resizingLeft || resizingRight)
{
dragTarget.setAttributeNS(null,"stroke","green");
}
else
{
dragTarget.setAttributeNS(null,"stroke","black");
}
}
}
function MouseMove(evt)
{
evt.stopPropagation();
if (dragTarget == null)
{
return;
}
if (resizingLeft)
{
if (window.console) console.log(evt.clientX + " " + evt.clientY);
deltaX = (clientPoint.x - evt.clientX);
if (window.console) console.log("deltaX = " + deltaX);
dragTarget.setAttributeNS(null,"width",rectWidth + deltaX);
dragTarget.setAttributeNS(null,"x",rectX - deltaX);
}
else if (resizingRight)
{
deltaX = (clientPoint.x - evt.clientX);
if (window.console) console.log("rectWidth = " + rectWidth + " deltaX = " + deltaX);
dragTarget.setAttributeNS(null,"width",rectWidth - deltaX);
}
else
{
var newXX = evt.clientX-grabPoint.x;
var newYX = evt.clientY-grabPoint.y;
dragTarget.setAttributeNS(null,'transform','translate(' + newXX + ',' + newYX + ')');
}
}
function MouseUp(evt)
{
evt.stopPropagation();
if (dragTarget == null)
{
return;
}
resizingLeft = false;
resizingRight = false;
resizingTop = false;
resizingBottom = false;
// var transMatrix = dragTarget.getCTM().inverse();
dragTarget.setAttributeNS(null,"stroke","blue");
dragTarget = null;
}
</script>
</body>
</html>
--
=======SVG ====
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
x="0px" y="0px" width="612px" height="792px" xml:space="preserve"
onmousedown="ecmascript:top.MouseDown(evt)"
onmousemove="ecmascript:top.MouseMove(evt)"
onmouseup="ecmascript:top.MouseUp(evt)">
<g id="rect1">
<rect id="rectTemplate" x="0" y="0" stroke="blue" width="100" height="30" />
</g>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我在我的答案中发布了一个拖动和调整转换后的 SVG 矩形大小的示例:
SVG 坐标与变换矩阵
您可以在我的网站上查看工作示例这里:
http://phrogz.net/svg/drag_under_transformation.xhtml
关键是:
mousedown
) 记录鼠标位置(在 SVG 全局空间中)。mousemove
) 计算拖动的偏移量(在 SVG 全局空间中),然后无论应用什么转换层次结构,这都有效(如我的示例所示)。
I have posted a sample of dragging and resizing transformed SVG rects in my answer here:
SVG coordinates with transform matrix
You can see the working example on my site here:
http://phrogz.net/svg/drag_under_transformation.xhtml
The key is to:
mousedown
) record the mouse location (in SVG global space).mousemove
) calculate the offset (in SVG global space) for the drag, and thenThis works regardless of the transformation hierarchy applied (as shown in my example).
您是否尝试过更改代码以围绕形状中心旋转形状?
这里是关于转换的 W3C 草案的摘录:
如果您设置 cx并将其移至功能区的中心,这可能有助于我从您的代码中获取上下文。
Have you tried to change your code to rotate the shape around the center of the shape?
Here is an excerpt of the W3C draft on transform:
If you set cx and cy to the center of your ribbon, this may help from what context I can pick up from your code.