根据clipPath元素更改要剪切的SVG路径

问题描述 投票:0回答:1
svg inkscape
1个回答
1
投票

ObjectUnSetClipPath
将删除剪辑属性
clip-path="url(#clip-path)"
– 而不是
<def>
剪辑路径本身。

但是如果你的clipPath定义被删除,你就不能剪辑任何元素。

function stripClip(el){
  let clipPaths = document.querySelector(el).querySelectorAll('clipPath');
  if(clipPaths.length){
    clipPaths.forEach(function(item, i){
      item.remove();
    }
    )
  }
}
svg{
width: 20vw;
}

.clipped{
clip-path: url(#clip-path2);
}
  <p><button onclick="stripClip('#svg1')" >remove ClipPath</button></p>
  
<svg id="svg1" data-name="Layer 1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 36 36">
  <defs>
    <style>...</style>
    <clipPath id="clip-path">
      <rect class="cls-1" x="10" width="36" height="18"/>
    </clipPath>
  </defs>
  <g class="cls-2">
   <path clip-path="url(#clip-path)" d="M18 2.0845
  a 15.9155 15.916 0 0 1 0 31.83
  a 15.916 15.916 0 0 1 0 -31.83z" fill="red" />
  <rect  clip-path="url(#clip-path)" x="0" y="0" width="10" height="25" />
  </g>
  </svg>
  
  
  <svg id="svg2" data-name="Layer 1"
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 36 36">
  <defs>
    <style>...</style>
    <clipPath id="clip-path2">
      <rect class="cls-1" x="10" width="36" height="18"/>
    </clipPath>
  </defs>
  <g class="cls-2">
   <path class="clipped" d="M18 2.0845
  a 15.9155 15.916 0 0 1 0 31.83
  a 15.916 15.916 0 0 1 0 -31.83z" fill="red" />
  <rect class="clipped" x="0" y="0" width="10" height="25" />
  </g>
  </svg>
  

编辑:使用 paper.js 获取 svg 交叉路径

诚然,这不是最方便的方法,但它是可能的:
除了 paper.js 之外,我们还需要一些脚本/帮助程序将 svg 形状(圆形、矩形等)转换为

<path>
元素(我正在使用 'pathThatSvg' ,因为 paper.js 只能基于 2 个路径元素计算新的交叉路径,如下所示:

var intersectionPath = path1.intersect(clipPath);

基于这个答案

var svg = document.querySelector("#svgIntersect");

// set auto ids for processing
function setAutoIDs(svg) {
  var svgtEls = svg.querySelectorAll(
    "path, polygon, rect, circle, line, text, g"
  );
  svgtEls.forEach(function (el, i) {
    if (!el.getAttribute("id")) {
      el.id = el.nodeName + "-" + i;
    }
  });
}
setAutoIDs(svg);

// convert shapes to paths
function shapesToPath(svg) {  
        pathThatSvg(svg.outerHTML).then((converted) => {
          var tmp = document.createElement("div");
          tmp.innerHTML = converted;
          svg.innerHTML = tmp.querySelector("svg").innerHTML;
        });
}
shapesToPath(svg);


function intersectPath(svg, decimals=2) {
  // init paper.js and add canvas
  canvas = document.createElement('canvas');
  canvas.id = "canvasPaper";
  canvas.setAttribute('style','display:none')
  document.body.appendChild(canvas);
  paper.setup("canvasPaper");

  // process clipped elements
  var all = paper.project.importSVG(svg, function (item, i) {
    item.position = new paper.Point(
      item.bounds.width / 2,
      item.bounds.height / 2
    );
    //item.scale(0.5, new Point(0, 0) )
    var items = item.getItems();
    var ids = item._namedChildren;

    var groups = item.children;
    groups.forEach(function (gr, i) {
      var group = gr["_namedChildren"];
      if (group) {
        for (key in group) {
          //get clip path
          var clip = group["clipPath"][0];
          if (key !== "clipPath") {
            var el = group[key][0];
             //get intersection path and generate d commands
            var elClipped = el.intersect(clip);
            var elClippedD = elClipped
              .exportSVG({ precision: decimals })
              .getAttribute("d");
            // select path by id and overwrite d attribute
            var newEl = svg.querySelector("#" + key);
            newEl.setAttribute("d", elClippedD);
          }
        }
      }
    });

    // remove clip defs and attributes
    var clippedEls = svg.querySelectorAll("[clip-path]");
    clippedEls.forEach(function (clippedEl, e) {
      clippedEl.removeAttribute("clip-path");
    });
    svg.querySelector("defs").remove();
    svg.classList.add("svg-intersect");
    console.log(svg.outerHTML)
  });
}
svg{
  border: 1px solid #ccc;
  display:inline-block;
  width:200px;
}

.svg-intersect path{
  stroke:red;
  stroke-width: 0.25;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.0/paper-full.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pathThatSvg.umd.min.js"></script>
<p>
  <button type="button" onclick="intersectPath(svg)">get Path Intersect</button>
</p>

<svg id="svgIntersect" viewBox="0 0 100 100">
  <defs>
    <clipPath id="clipPath">
      <circle cx="25" cy="25" r="25"/>
    </clipPath>
  </defs>
  <g id="clipGroup" clip-path="url(#clipPath)">
    <circle fill="#999" data-id="circle" cx="25" cy="25" r="25" />
    <rect fill="#555" id="rect" x="25" y="25" width="50" height="50" />
  </g>
  
  <g  clip-path="url(#clipPath)">
    <circle fill="#444" id="circle2" cx="66" cy="25" r="25" />
    <rect fill="#22" id="rect2" x="15" y="12.5" width="20" height="75" />
  </g>
</svg>

© www.soinside.com 2019 - 2024. All rights reserved.