2012-01-20 36 views
9

我很努力地找到一种方法,用鼠标动态调整和拖动svg多边形。不幸的是,jQueryUi不适用于svg元素。我也检查了拉斐尔图书馆,但无法找到任何文件/片段如何实现这一点。动态调整和拖动SVG多边形

除了使用SVG,还有其他方法可以动态调整和拖动多边形图形吗?

回答

13

你可以自己使用SVG元素。特别是,您可以找到多边形的点并添加可用jQuery拖动的HTML元素句柄。 (我假设你遇到的问题是jQuery UI不支持SVG定位模型。)下面是我刚刚写的一个完整示例(在Safari 5和Firefox 9中测试过)。

(免责声明:我不是jQuery的一个普通用户,这个代码可以是unidiomatic的方式,除了不使用jQuery的一切)

<!DOCTYPE html> 
 
<html><head> 
 
    <title>untitled</title> 
 

 
    <style type="text/css" media="screen"> 
 
    .handle { 
 
     position: absolute; 
 
     border: 0.1em solid black; 
 
     width: 1em; 
 
     height: 1em; 
 
    } 
 
    </style> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script> 
 

 
    <script type="text/javascript"> 
 
    function draggablePolygon(polygon) { 
 
    var points = polygon.points; 
 
    var svgRoot = $(polygon).closest("svg"); 
 
    
 
    for (var i = 0; i < points.numberOfItems; i++) { 
 
     (function (i) { // close over variables for drag call back 
 
     var point = points.getItem(i); 
 

 
     var handle = document.createElement("div"); 
 
     handle.className = "handle"; 
 
     document.body.appendChild(handle); 
 

 
     var base = svgRoot.position(); 
 
     // center handles over polygon 
 
     var cs = window.getComputedStyle(handle, null); 
 
     base.left -= (parseInt(cs.width) + parseInt(cs.borderLeftWidth) + parseInt(cs.borderRightWidth))/2; 
 
     base.top -= (parseInt(cs.height) + parseInt(cs.borderTopWidth) + parseInt(cs.borderBottomWidth))/2; 
 

 
     handle.style.left = base.left + point.x + "px"; 
 
     handle.style.top = base.top + point.y + "px"; 
 

 
     $(handle).draggable({ 
 
      drag: function (event) { 
 
      setTimeout(function() { // jQuery apparently calls this *before* setting position, so defer 
 
       point.x = parseInt(handle.style.left) - base.left; 
 
       point.y = parseInt(handle.style.top) - base.top; 
 
      },0); 
 
      } 
 
     }); 
 
     }(i)); 
 
    } 
 
    } 
 
    </script> 
 
</head><body> 
 
    <p> 
 
    (Offset to test) 
 
    <svg id="theSVG" width="500" height="500" style="border: 2px inset #CCC;"> 
 
     <polygon id="x" points="200,200 100,100 100,1" fill="green" /> 
 
     <polygon id="y" points="200,200 100,100 1,100" fill="red" /> 
 
    </svg> 
 
    </p> 
 
    <script type="text/javascript"> 
 
    draggablePolygon(document.getElementById("x")); 
 
    draggablePolygon(document.getElementById("y")); 
 
    </script> 
 

 
</body></html>

你也可以附加一个事件处理程序添加到SVG多边形并实现拖动(我测试过并且这可以工作),但是您必须在多边形的当前边界内单击,这是一个非典型的UI并且可能很棘手,并且实现您自己的点击测试。

为此,您需要为多边形元素添加onmousedown处理函数。然后检索它的点,找到点击位置的范围,存储最初的鼠标位置,然后当鼠标位置改变时让处理器修改点的xy

+0

谢谢!我正在研究拖动 - 在边界内单击正是我想要的。 另外我想用svg-text来标记这些多边形,但我没有想出如何更新文本位置,同时调整多边形的大小。你可以给任何提示吗? – user1159545

+1

当然,我添加了一个提示。不幸的是,我没有保存我先写的代码。 –

+0

嘿,我面临的问题是,我需要更新多边形的坐标,因为我正在调整它的大小。当我用萤火虫检查一个调整大小的多边形元素时,虽然它已被调整大小,但它仍然具有旧点。任何想法如何解决这个问题? – user1159545