我在使用导入的SVG时遇到了各个元素的问题,并希望以某种方式提供建议。
我在Illustrator中创建了一个SVG,它有几个层,最终成为组元素。 当我从服务器检索SVG时,我得到类似的东西。
<svg>
<g>
<g>
</svg>
我不想将图像放在一起,所以我将它们分组,然后用自己的svg标签围住它们,然后放在页面上。
<svg>
<g>
</svg>
<svg>
<g>
</svg>
这很棒,就像我想要的那样。
我的问题在于,每个项目的路径都是在原始文件中绘制的。它们都是从Illustrator文件中抽出的(0,0),所以当我尝试放置它们时,它们左边都有大量的空白区域,其他元素曾经存在。
我尝试过使用transform =“translate(-50,-50)”或其他什么,它确实会移动元素,但由于它们没有x,y属性,我不知道在哪里移动它们。< / p>
有没有人知道偏移绘制路径的方法?或者,如果有办法读取SVG并将其分解为每个单独的元素并使用?
当使用萤火虫或铬时,它们会向我显示具有正确尺寸的单个元素,但由于在Illustrator中绘制的路径的位置,它们被放置了大量的空白区域。
我已经尝试了contentDocument
,documentElement
,这两个都是空的。也许我使用它们错了?
我是一个繁重的ActionScript开发人员,现在正在使用Javascript和jQuery,所以我习惯使用x,y coord系统和放置元素,但这似乎不是它应该工作的方式:/
答案 0 :(得分:4)
如果你真的想要获得路径的XY部分,我写了一个function to convert paths to use all-absolute commands。通过这个,您可以运行路径命令(使用pathSegList
DOM接口,而不是原始字符串属性)并提取所有X / Y值,并按照您的意愿进行操作。
但是,更简单的是简单地calculate the bounding box of the path并设置<svg>
元素上的viewBox
以直接适应这一点:
// In case you want to leave the old SVG document unchanged
var newGroup = oldGroup.cloneNode(true);
var newSVG = document.createElementNS('http://www.w3.org/2000/svg','svg');
newSVG.appendChild(newGroup);
var bbox = newGroup.getBBox();
newSVG.setAttribute(
'viewBox',
[bbox.x,bbox.y,bbox.width,bbox.height].join(' ')
);
上述答案未正确考虑已将transform
应用于您要移动的群组的情况。 (边界框在元素的未转换空间中返回。)我创建了一个解释此问题的演示,计算转换元素的正确边界框。
// Find all the root groups in the original SVG file
var rootGroups = document.querySelectorAll('svg > g');
for (var i=rootGroups.length;i--;){
var newSVG = elementToSVG(rootGroups[i]);
document.body.appendChild(newSVG);
}
// Create a new SVG wrapping around a copy of the element
// with the viewBox set to encompass the element exactly
function elementToSVG(el){
var old = el.ownerSVGElement,
svg = document.createElementNS(old.namespaceURI,'svg'),
css = old.querySelectorAll('style,defs');
// Preserve elements likely needed for correct appearance
[].forEach.call(css,copyToNewSVG);
copyToNewSVG(el);
var bb = globalBoundingBox(el);
svg.setAttribute('viewBox',[bb.x,bb.y,bb.width,bb.height].join(' '));
return svg;
function copyToNewSVG(e){
svg.appendChild(e.cloneNode(true));
}
}
// Calculate the bounding box of an element in global SVG space
// accounting for transforms applied to the element
function globalBoundingBox(el){
var bb = el.getBBox(),
svg = el.ownerSVGElement,
m = el.getTransformToElement(svg);
var 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=Infinity,xMax=-Infinity,yMin=Infinity,yMax=-Infinity;
pts.forEach(function(pt){
pt = pt.matrixTransform(m);
xMin = Math.min(xMin,pt.x);
xMax = Math.max(xMax,pt.x);
yMin = Math.min(yMin,pt.y);
yMax = Math.max(yMax,pt.y);
});
bb = {}; //IE9 disallows mutation of the original bbox
bb.x = xMin; bb.width = xMax-xMin;
bb.y = yMin; bb.height = yMax-yMin;
return bb;
}