Вот то, что я придумал, в действии: Расположение элемента HTML в 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+')' );
Предостережения:
- Отлично работает в Firefox v7
- Работает для Chrome v16 и Safari v5, за исключением:
- Не работает, еслизум браузера был отрегулирован.
- Не работает, если
<foreignObject>
был повернут или перекошен, из-за этой ошибки Webkit .
- Он не работает для IE9 (XHTML не отображается, а
getTransformToElement
не работает).