Javascript 将SVG中的组拆分为围绕内容定位的子图像

Javascript 将SVG中的组拆分为围绕内容定位的子图像,javascript,jquery,svg,Javascript,Jquery,Svg,我对导入的SVG中的单个元素有问题,希望能提供一些建议 我在Illustrator中创建了一个SVG,它有几个层,最后是组元素。 当我从服务器检索SVG时,我得到了类似于的东西 我不想将图像作为一个整体放置,所以我将其按组分解,并用各自的svg标记将每个图像包围起来,然后放置在页面上 这很好,就像我想要的那样 我的问题在于,在原始文件中绘制这些项的路径。它们都是从Illustrator文件中提取的(0,0),所以当我尝试放置它们时,它们在左侧都有大量的空白区域,其他元素曾经存在的地方 我

我对导入的SVG中的单个元素有问题,希望能提供一些建议

我在Illustrator中创建了一个SVG,它有几个层,最后是组元素。 当我从服务器检索SVG时,我得到了类似于的东西


我不想将图像作为一个整体放置,所以我将其按组分解,并用各自的svg标记将每个图像包围起来,然后放置在页面上


这很好,就像我想要的那样

我的问题在于,在原始文件中绘制这些项的路径。它们都是从Illustrator文件中提取的(0,0),所以当我尝试放置它们时,它们在左侧都有大量的空白区域,其他元素曾经存在的地方

我尝试过使用transform=“translate(-50,-50)”或其他方法来移动元素,但由于它们没有x,y属性,我不知道在哪里移动它们

有人知道偏移绘制的路径的方法吗?或者,是否有一种方法可以读取SVG并将其分解为每个单独的元素并使用它

当使用firebug或chrome时,它们会向我显示大小正确的单个元素,但由于Illustrator中绘制的路径的位置,它们被放置在大量空白处

我尝试了
contentDocument
documentElement
,但都显示为空。也许我用错了


我是一名动作脚本开发人员,现在使用Javascript和jQuery,因此我习惯于x、y坐标系统和放置元素,但这似乎不是它应该使用的方式://

如果您真的想获得我编写的路径的XY部分。这样,您就可以运行path命令(使用DOM接口,而不是原始字符串属性),并提取所有X/Y值,然后根据需要使用它们

但是,更简单的方法是简单地将
元素上的设置为直接与之匹配:

//如果希望保持旧SVG文档不变
var newGroup=oldGroup.cloneNode(true);
var newSVG=document.createElements('http://www.w3.org/2000/svg'、'svg');
newSVG.appendChild(newGroup);
var bbox=newGroup.getBBox();
newSVG.setAttribute(
“查看框”,
[bbox.x,bbox.y,bbox.width,bbox.height]。连接(“”)
);
上述答案不能正确地解释将
转换应用于要移动的组的情况。(边界框在元素的未转换空间中返回。)我创建了一个演示来解释这一点,为转换后的元素计算正确的边界框

演示:
//在原始SVG文件中查找所有根组
var rootGroups=document.querySelectorAll('svg>g');
for(var i=rootGroups.length;i--;){
var newSVG=elementToSVG(根组[i]);
document.body.appendChild(newSVG);
}
//围绕元素的副本创建一个新的SVG包装
//将viewBox设置为完全包围图元
功能元件TOSVG(el){
var old=所有者权益,
svg=document.createElements(旧的.namespaceURI,'svg'),
css=old.querySelectorAll('style,defs');
//保留正确外观可能需要的元素
[]forEach.call(css、copyToNewSVG);
copyToNewSVG(el);
var bb=全局边界框(el);
setAttribute('viewBox',[bb.x,bb.y,bb.width,bb.height].join('');
返回svg;
函数copyToNewSVG(e){
appendChild(e.cloneNode(true));
}
}
//计算全局SVG空间中元素的边界框
//计算应用于元素的变换
函数全局边界框(el){
var bb=el.getBBox(),
svg=el.ownerSVGElement,
m=el.GetTransfermToElement(svg);
变量pts=[
svg.createSVGPoint(),svg.createSVGPoint(),
svg.createSVGPoint(),svg.createSVGPoint()
];
pts[0].x=bb.x;pts[0].y=bb.y;
pts[1].x=bb.x+bb.width;pts[1].y=bb.y;
pts[2].x=bb.x+bb.width;pts[2].y=bb.y+bb.height;
pts[3].x=bb.x;pts[3].y=bb.y+bb.height;
var xMin=无穷大,xMax=-无穷大,yMin=无穷大,yMax=-无穷大;
forEach临时秘书处(职能(pt){
pt=pt.矩阵变换(m);
xMin=Math.min(xMin,pt.x);
xMax=Math.max(xMax,pt.x);
yMin=数学最小值(yMin,pt.y);
yMax=数学最大值(yMax,pt.y);
});
bb={};//IE9不允许原始bbox的突变
bb.x=xMin;bb.width=xmaxxmin;
bb.y=yMin;bb.height=yMax-yMin;
返回bb;
}

我看到了
getBBox()
,但它不会工作或返回任何东西。我是在jQuery元素
$('#box').getBBox()
而不是JS
document.getElementById('box').getBBox()中使用它的。这使我能够使用
transform
获取所需的数据,以调整SVG元素的大小并将其移动到所需的位置。另外,感谢您的绝对功能!如果我的应用程序进程不喜欢我的偏移量值进行处理,但转换为绝对值应该可以解决这个问题,那么我可能最终会使用它。再次感谢!您遇到的问题是,
$('#box')
返回一个“jQuery对象”(一个DOM元素数组,数组中有特殊方法可用)。您可以使用
$('#box')[0].getBBox()
$('#box').get(0).getBBox()
对所选DOM元素进行操作。我尝试使用上述示例,每个bbox返回0,0,0。知道为什么会这样吗?您的组必须位于SVG文档中,并且SVG文档必须位于页面上,否则
getBox()
将始终返回0。是的,就是这样,而不是仅存储在var:p中的页面上,不断发现您如何从DOM和Flash的显示列表中交互和检索属性的差异。再次感谢你的帮助!