如何使用 javascript 从主 svg 对象动态创建 svg 视图框?
How can I dynamically create svg viewboxes from a master svg object using javascript?
我的页面上有一个非常大且复杂的 svg 元素。我的目标是使 svg 以各种尺寸打印,一直到绘图仪比例。如果图形大于纸张尺寸,图像需要平铺以跨越多个页面。理想情况下,浏览器(针对 Firefox 38)将为我 tile/wrap svg 图形,但这似乎不可能。如果我将 svg 图形缩放到适当的大小并打印它,超出页面边界的任何内容都会被截断。
作为这个问题的解决方案,我可以将 svg 拆分为多个设置了 viewBox 属性的较小切片 svg 元素,并将切片 svg 的内容设为 <use></use>
标记,如下所示:
<div id="SVGMasterDiv">
<svg id="SVGMaster" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="4903.745578" height="1092.0904763600001" xml:space="preserve">
<!-- a lot of svg here -->
</svg>
</div>
<div id="SVGAttribObj" data-canvaswidth="2451.872789" data-canvasheight="546.0452381800001"></div>
<div id="SVGSlicesDiv">
<svg viewbox="0 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in" style="">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="245.1872789 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="490.3745578 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="735.5618367 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="980.7491156 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="1225.9363945 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="1471.1236734 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="1716.3109523 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="1961.4982312 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="2206.6855101 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
</div>
如果我将其保存到 html 文件中,效果很好。
问题是我需要动态地执行此操作——所以我的页面上有一个下拉菜单,允许用户指定以英寸为单位的高度以将 svg 缩放到,以及要制作的切片数量和 javascript 函数创建切片 svg 元素。
function Coordsheet_MakeLayoutPrintable(numSlices, pageHeight){
// This function divides the SVGMaster into slices that may be printed
// The new elements will be placed in the same div as the SVGMaster div
// Determine where to put the child divs
var holderDiv = document.getElementById('SVGSlicesDiv');
holderDiv.innerHTML = "";
// Get the attributes saved when the SVGMaster was created
var attribObj = document.getElementById('SVGAttribObj');
var width = parseFloat(attribObj.getAttribute('data-canvasWidth'))
var height = parseFloat(attribObj.getAttribute('data-canvasHeight'))
// Make a series of containers for the svg element in the result holder div
var blockWidth = width / numSlices;
var pageWidth = blockWidth * pageHeight/height;
for (var i = 0; i < numSlices; i++) {
x = i * blockWidth;
var s = document.createElement('svg');
s.innerHTML = '<use xlink:href="#SVGMaster">';
s.setAttribute("viewBox", x + " " + 0 + " " + (blockWidth) + " " + (height));
s.setAttribute("width", blockWidth);
s.setAttribute("height", height);
// Viewport size (size visible)
s.setAttribute("height", pageHeight + "in");
s.setAttribute("width", pageWidth + "in");
holderDiv.appendChild(s);
}
}
这会导致上面显示的 html,但由于某种原因,更新未显示在页面上。我如何让浏览器重新加载 svg(或其他)以便 viewBox 切片更新?
tl;dr:为什么 viewBox svg 元素在动态生成时不呈现?
您不能使用 createElement 创建 SVG 元素,那样只会创建 html 个元素。您必须改用 createElementNS 即
var s = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
我的页面上有一个非常大且复杂的 svg 元素。我的目标是使 svg 以各种尺寸打印,一直到绘图仪比例。如果图形大于纸张尺寸,图像需要平铺以跨越多个页面。理想情况下,浏览器(针对 Firefox 38)将为我 tile/wrap svg 图形,但这似乎不可能。如果我将 svg 图形缩放到适当的大小并打印它,超出页面边界的任何内容都会被截断。
作为这个问题的解决方案,我可以将 svg 拆分为多个设置了 viewBox 属性的较小切片 svg 元素,并将切片 svg 的内容设为 <use></use>
标记,如下所示:
<div id="SVGMasterDiv">
<svg id="SVGMaster" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="4903.745578" height="1092.0904763600001" xml:space="preserve">
<!-- a lot of svg here -->
</svg>
</div>
<div id="SVGAttribObj" data-canvaswidth="2451.872789" data-canvasheight="546.0452381800001"></div>
<div id="SVGSlicesDiv">
<svg viewbox="0 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in" style="">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="245.1872789 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="490.3745578 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="735.5618367 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="980.7491156 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="1225.9363945 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="1471.1236734 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="1716.3109523 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="1961.4982312 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
<svg viewbox="2206.6855101 0 245.1872789 546.0452381800001" width="1.3470712411148744in" height="3in">
<use xlink:href="#SVGMaster"></use>
</svg>
</div>
如果我将其保存到 html 文件中,效果很好。
问题是我需要动态地执行此操作——所以我的页面上有一个下拉菜单,允许用户指定以英寸为单位的高度以将 svg 缩放到,以及要制作的切片数量和 javascript 函数创建切片 svg 元素。
function Coordsheet_MakeLayoutPrintable(numSlices, pageHeight){
// This function divides the SVGMaster into slices that may be printed
// The new elements will be placed in the same div as the SVGMaster div
// Determine where to put the child divs
var holderDiv = document.getElementById('SVGSlicesDiv');
holderDiv.innerHTML = "";
// Get the attributes saved when the SVGMaster was created
var attribObj = document.getElementById('SVGAttribObj');
var width = parseFloat(attribObj.getAttribute('data-canvasWidth'))
var height = parseFloat(attribObj.getAttribute('data-canvasHeight'))
// Make a series of containers for the svg element in the result holder div
var blockWidth = width / numSlices;
var pageWidth = blockWidth * pageHeight/height;
for (var i = 0; i < numSlices; i++) {
x = i * blockWidth;
var s = document.createElement('svg');
s.innerHTML = '<use xlink:href="#SVGMaster">';
s.setAttribute("viewBox", x + " " + 0 + " " + (blockWidth) + " " + (height));
s.setAttribute("width", blockWidth);
s.setAttribute("height", height);
// Viewport size (size visible)
s.setAttribute("height", pageHeight + "in");
s.setAttribute("width", pageWidth + "in");
holderDiv.appendChild(s);
}
}
这会导致上面显示的 html,但由于某种原因,更新未显示在页面上。我如何让浏览器重新加载 svg(或其他)以便 viewBox 切片更新?
tl;dr:为什么 viewBox svg 元素在动态生成时不呈现?
您不能使用 createElement 创建 SVG 元素,那样只会创建 html 个元素。您必须改用 createElementNS 即
var s = document.createElementNS('http://www.w3.org/2000/svg', 'svg');