将 SVG 中的组拆分为位于内容周围的子图像
Split groups in SVG into sub-images positioned around the contents
我在导入的 SVG 中遇到单个元素的问题,希望以某种方式提供建议。
我在 Illustrator 中创建了一个 SVG,其中包含多个图层,最终成为组元素。当我从服务器检索SVG时,我得到类似的东西。
<svg>
<g>
<g>
</svg>
我不想将图像作为一个整体放置,所以我按组将其分解,并用自己的 svg 标签包围每个图像,然后放置在页面上。
<svg>
<g>
</svg>
<svg>
<g>
</svg>
这很棒,就像我想要的那样工作。
我的问题是,这些项目中每个项目的路径都是在原始文件中绘制的。它们都是从 Illustrator 文件中绘制出来的 (0,0(,所以当我尝试放置它们时,它们在左侧都有大量的空白区域,其他元素曾经存在过。
我尝试使用 transform="translate(-50,-50(" 或其他什么,它确实移动了元素,但由于它们没有 x,y 属性,我不知道在哪里移动它们。
有谁知道抵消绘制路径的方法?或者,如果有一种方法可以读取 SVG 并将其分解为每个单独的元素并使用?
当使用Firebug或chrome时,它们以正确的大小向我显示单个元素,但由于Illustrator中绘制的路径的位置,它们被放置了很多空白。
我试过contentDocument
,documentElement
,这两个都显示为空。也许我用错了?
我是一个重度的Actionscript开发人员,现在使用Javascript和jQuery,所以我习惯了x,y坐标系统和放置元素,但这似乎不是它应该工作的方式:/
如果你真的想获取路径的XY部分,我写了一个函数来转换路径以使用全绝对命令。有了这个,您可以运行路径命令(使用 pathSegList
DOM 接口,而不是原始字符串属性(并提取所有 X/Y 值并执行您想要的操作。
但是,更简单的是简单地计算路径的边界框,并在<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
已应用于要移动的组的情况。(边界框在元素的未转换空间中返回。我创建了一个演示来解释这一点,为转换后的元素计算正确的边界框。
演示:http://phrogz.net/SVG/explode_svg_components.xhtml
// 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;
}
- jQuery+Android.将功能(Touchstart、touchmove)应用于实时加载的内容
- 如何将Angular2管道应用于动态内容
- 阻止Jquery对话框内容的CSS应用于主窗口
- tinyMCE删除背景图像:“"类似于magento的url的内容
- 在事件处理中,将内容脚本优先于本地脚本
- 如何将javascript应用于我的webView's的html内容
- 容器宽度远大于内容
- JQuery验证仅适用于提交的表单中的第一个元素.[打算验证所有内容]
- JQuery对话框,其内容依赖于javascript
- 打开一个模态(在Codeigniter中),该模态从依赖于phpvar的URL加载(在iframe中)内容
- 添加混合 javascript 函数,使内容淡入列内的另一个内容/使其适用于两个单独的列
- 是否有类似于“$(window).load();”的东西用于在新插入的 Ajax 内容完成加载后执行函数
- 无法让单元格专注于内容可编辑脚本
- 点击 Chrome 桌面通知即可专注于内容
- 如何将css加载程序仅应用于内容的一个特定部分
- 固定位置的响应图像周围的内容
- jQuery滚动按钮,受限于内容的数量
- 选择css类依赖于内容
- 当asp.net控件不存在于内容页中时,母版javascript会导致对象引用错误
- 在ASP.NET中加载文本框周围的内容