为了账号安全,请及时绑定邮箱和手机立即绑定

将 SVG 拆分为多个部分 - Javascript

将 SVG 拆分为多个部分 - Javascript

12345678_0001 2021-11-12 17:42:29
我有一个很大的 svg 标签,里面有很多 svg 多边形、线条、文本,制作了一个 2D 地图,需要溢出才能在屏幕上看到它的全尺寸,就像这样:当我单击“打印”或使用“ctrl + p”时,我需要一种从浏览器打印它的方法,但是为此我需要将它分成几部分然后放在列布局上,这样它们就可以适合 A4 大小来打印整个内容,类似这样:当我尝试打印时,我得到了这个:所以,我需要一种方法来将这个 svg 字段分成几部分以适合要打印的页面。有没有办法做到这一点,使用js,css,任何东西?谢谢!
查看完整描述

1 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

没有办法用纯 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>


查看完整回答
反对 回复 2021-11-12
  • 1 回答
  • 0 关注
  • 858 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号