javascript - 将 SVG 分成几部分 - Javascript

标签 javascript svg split cut

我有一个很大的 svg 标签,里面有很多 svg 多边形、线条、文本,用来制作 2D map ,需要溢出才能在屏幕上看到它的全尺寸,类似这样:

enter image description here

当我单击“打印”或使用“ctrl + p”时,我需要一种从浏览器打印它的方法,但为此我需要将其分成几部分,然后放在列布局上,这样它们就可以适合 A4 尺寸打印整个内容,类似这样:

enter image description here

当我尝试打印时,我得到这个:

enter image description here

因此,我需要一种方法将此 svg 字段分成几部分以适合要打印的页面。 有什么办法可以做到这一点,使用js、css之类的吗?谢谢!

最佳答案

纯 CSS 无法实现您想要的功能。

您需要 Javascript 来创建 SVG 的分割部分。

这是一些演示代码。我在代码中留下了注释来解释它是如何工作的。

该示例使用复选框来模拟“打印模式”,但您可以在打印时通过监听 beforeprintafterprint 事件自动运行拆分和未拆分功能.

https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeprint

function  splitSVGs(splitWidth) {
  let splittables = document.querySelectorAll(".splittable");
  splittables.forEach(function(svgElem) {

    // Get starting size of the original SVG now
    const computed = getComputedStyle(svgElem);
    const width = parseInt(computed.width, 10);
    const height = parseInt(computed.height, 10);
    const vB = svgElem.viewBox.baseVal;
    // Get the viewBox of the SVG also
    const bbox = (svgElem.getAttribute("viewBox") !== null) ? {x:vB.x, y:vB.y, width:vB.width, height:vB.height}
                                                            : {x:0, y:0, width, height};
    // Hide the original SVG
    svgElem.classList.add("hide");
    
    // Create a temporary div element to hold our generated sections
    const div = document.createElement("div");
    div.classList.add("sections");
    svgElem.insertAdjacentElement('afterend', div);

    let remainingWidth = width;
    while (remainingWidth > 0) {
      const sectionWidth = Math.min(splitWidth, remainingWidth);
      // Convert sectionWidth relative to viewBox
      bbox.width = sectionWidth * bbox.height / height;

      // Create an SVG element to contain one section of the split
      const section = document.createElementNS("http://www.w3.org/2000/svg", "svg");
      section.setAttribute("width", sectionWidth);
      // Add a viewBox that shows the area of the original that we want to see in this section
      section.setAttribute("viewBox", [bbox.x, bbox.y, bbox.width, bbox.height].join(' '));
      
      // Add a <use> element to the section SVG that references the original
      const use = document.createElementNS("http://www.w3.org/2000/svg", "use");
      use.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", '#'+svgElem.id);
      use.setAttribute("width", vB.width);
      use.setAttribute("height", vB.height);
      section.appendChild(use);
      
      // Add this section SVG to the sections div
      div.appendChild(section);
      // How much of the original SVG width is left?
      remainingWidth -= splitWidth;
      // Update bbox so the next SVG will show the next section of the original
      bbox.x += bbox.width;
    }

  });
  
}


function unsplitSVGs() {
  // Get rid of the generated sections
  const sections = document.querySelectorAll(".sections");
  sections.forEach(function(div) {
    div.remove();
  });
  
  // Unhide all the original SVGs
  const splittables = document.querySelectorAll(".splittable");
  splittables.forEach(function(svgElem) {
    svgElem.classList.remove("hide");
  });
  
}


document.getElementById("print-mode").addEventListener("change", function(evt) {
  if (evt.target.checked) {
    splitSVGs(600);
  } else {
    unsplitSVGs();
  }
});
svg {
  background: linen;
}

svg#test {
  width: 2960px;
  height: 80px;
  border: solid 2px black;
}

/* Hide while still keeping the contents visible to our section SVGs */
.hide {
  position: absolute;
  top: -9999px;
}

.sections svg {
  border: solid 2px black;
}

.sections svg:not(:first-child) {
  border-left: dashed 2px black;
}

.sections svg:not(:last-child) {
  border-right: dashed 2px black;
}
<p>
<input type="checkbox" id="print-mode">
<label for="print-mode"> Simulate print mode (split the SVG)</label>
</p>

<svg viewBox="0 0 1480 40" id="test" class="splittable">
  <text x="10" y="30" font-size="30px">We choose to go to the Moon in this decade and do the other things, not because they are easy, but because they are hard.</text>
</svg>

关于javascript - 将 SVG 分成几部分 - Javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58286732/

相关文章:

javascript - 如何在 Clojurescript REPL 中显示生成的 JS?

javascript - 在高级监听器中获取对 d3 中事件目标的引用?

css - 检测浏览器对 CSS 动画 SVG 的支持

python - 从 pandas 数据框中删除句子长度超过特定字长的行

python - 将数据帧拆分为多个数据帧

javascript - LF 或 CRLF 的 Visual Studio 代码安装 eslint 错误

javascript - 当我想使用 _.lodash 将一个数组转换为另一个数组时,reduce 是使用 map 的替代方法吗?

javascript - 如何在密码字段中显示文本

html - 带剪辑路径的三 Angular 形 ||多余 "clipping"的背景?

javascript - 尝试将数组拆分为字符数组时出现间歇性类型错误