2011-11-06 167 views
2

我有一个带有XHTML表的SVG文件。我想用SVG绘图(通过JavaScript)连接表的一部分。例如,在下面的文件我想将每个集中在红色边框的右端的黄色圆圈的:SVG空间中的foreignObject HTML元素的坐标

<?xml version="1.0"?> 
<svg viewBox="0 0 1000 650" version="1.1" baseProfile="full" 
    xmlns="http://www.w3.org/2000/svg"> 
    <title>Connect</title> 
    <style type="text/css"><![CDATA[ 
    table { border-collapse:collapse; margin:0 auto; } 
    table td { padding:0; border-bottom:1px solid #c00;} 
    circle.dot { fill:blue } 
    ]]></style> 
    <foreignObject x="100" width="800" height="600" y="400"><body xmlns="http://www.w3.org/1999/xhtml"><table><thead><tr> 
    <th>Space</th> 
    </tr></thead><tbody> 
    <tr><td><input name="name" type="text" value="One"/></td></tr> 
    <tr><td><input name="name" type="text" value="Two"/></td></tr> 
    </tbody></table></body></foreignObject> 
    <circle class="dot" id="dot1" cx="100" cy="100" r="5" /> 
    <circle class="dot" id="dot2" cx="200" cy="100" r="5" /> 
</svg> 

我怎样才能最好地发现在全球SVG坐标空间中的任意HTML元素的位置?

为简单起见,请随意忽略浏览器大小调整以及可能包装<foreignObject>的任何转换堆栈。

回答

2

这里是我想出了,在行动:HTML Element Location in SVG (v2)

// Find the four corners (nw/ne/sw/se) of any HTML element embedded in 
// an SVG document, transformed into the coordinates of an arbitrary SVG 
// element in the document. 
var svgCoordsForHTMLElement = (function(svg){ 
    var svgNS= svg.namespaceURI, xhtmlNS = "http://www.w3.org/1999/xhtml"; 
    var doc = svg.ownerDocument; 
    var wrap = svg.appendChild(doc.createElementNS(svgNS,'foreignObject')); 
    var body = wrap.appendChild(doc.createElementNS(xhtmlNS,'body')); 
    if (typeof body.getBoundingClientRect != 'function') return; 
    body.style.margin = body.style.padding = 0; 
    wrap.setAttribute('x',100); 
    var broken = body.getBoundingClientRect().left != 0; 
    svg.removeChild(wrap); 
    var pt = svg.createSVGPoint(); 
    return function svgCoordsForHTMLElement(htmlEl,svgEl){ 
    if (!svgEl) svgEl = htmlEl.ownerDocument.documentElement; 
    for (var o=htmlEl;o&&o.tagName!='foreignObject';o=o.parentNode){} 
    var xform = o.getTransformToElement(svgEl); 
    if (broken) xform = o.getScreenCTM().inverse().multiply(xform); 

    var coords = {}; 
    var rect = htmlEl.getBoundingClientRect(); 
    pt.x = rect.left; pt.y = rect.top; 
    coords.nw = pt.matrixTransform(xform); 
    pt.y = rect.bottom; coords.sw = pt.matrixTransform(xform); 
    pt.x = rect.right; coords.se = pt.matrixTransform(xform); 
    pt.y = rect.top; coords.ne = pt.matrixTransform(xform); 

    return coords; 
    }; 
})(document.documentElement); 

这里是你如何使用它:

// Setting SVG group origin to bottom right of HTML element 
var pts = svgCoordsForHTMLElement(htmlEl); 
var x = pts.sw.x, y = pts.sw.y; 
svgGroup.setAttribute('transform', 'translate('+x+','+y+')'); 

注意事项:

  • 它完美的火狐v7
  • 它工作f或Chrome v16和Safari v5,但以下情况除外:
    • 如果浏览器缩放已调整,则不起作用。
    • 由于this Webkit bug,如果<foreignObject>已被旋转或倾斜,则不起作用。
  • 它不适用于IE9(XHTML不显示,并且getTransformToElement不起作用)。