首页 > 解决方案 > SVG 或 Canvas,如何按坐标和 div 大小切割正方形

问题描述

我的问题是下一个。如何生成一个 SVG 或 Canvas 就像全屏页面覆盖(50% 透明)。但我想突出显示此叠加层下方的一些 div。我知道那个 div 的坐标和宽高。如何根据叠加层上的 div 剪切区域,以便该区域完全透明并清楚地看到该 div?该 div 将位于不同页面的不同位置。我不擅长画布也不擅长svg。请帮我。

标签: javascriptcsshtmlsvgcanvas

解决方案


我希望这是你需要的。在 DOM 上,您有 2 个 div:#square#circle.

我正在使用一个半透明(不透明度 0.9)的叠加层,该叠加层被#square. 请阅读我的评论。

var SVG_NS = 'http://www.w3.org/2000/svg';
// define the position of the #square
let _left = 120;
let _top = 230; 
let w = 150;
let h = 150;

// recalculate the points needed for the clip-path
 let p = svg.createSVGPoint();
 p.x = _left;
 p.y = _top;
 let ctm = svg.getScreenCTM().inverse();
 p =  p.matrixTransform(ctm);

 let p1 = svg.createSVGPoint();
 p1.x = w;
 p1.y = h;
 let ctm1 = svg.getScreenCTM().inverse();
 p1 =  p1.matrixTransform(ctm1);


//define the d for the clip path
let oClipRect={
  d:`M0,0L100,0L100,500L0,500L0,0
  M${p.x+p1.x},${p.y}
  L${p.x},${p.y}
  L${p.x},${p.y+p1.y}
  L${p.x+p1.x},${p.y+p1.y}
  L${p.x+p1.x},${p.y}`,
  id:"clip_rect"
}

//a big overlay rectangle that gets clipped
//The rectangle is semitransparent so that you can see the the circle
let oRect={
  width:"100%",
  height:"100%",
  "clip-path":"url(#_clip)",
  fill:"rgba(0,0,0,.9)"
}


drawElmt(oClipRect,"path", _clip);
drawElmt(oRect,"rect", svg);

// function update needed on resize
function update(){
 p = svg.createSVGPoint();
 p.x = _left;
 p.y = _top;
 ctm = svg.getScreenCTM().inverse();
 p =  p.matrixTransform(ctm);

 p1 = svg.createSVGPoint();
 p1.x = w;
 p1.y = h;
 ctm1 = svg.getScreenCTM().inverse();
 p1 =  p1.matrixTransform(ctm1);
 
 d = `M0,0L100,0L100,500L0,500L0,0
  M${p.x+p1.x},${p.y}
  L${p.x},${p.y}
  L${p.x},${p.y+p1.y}
  L${p.x+p1.x},${p.y+p1.y}
  L${p.x+p1.x},${p.y}`;
  console.log(d)

 clip_rect.setAttributeNS(null,"d",d);
 
}



setTimeout(function() {
		update();
		addEventListener('resize', update, false);
}, 15);




function drawElmt(o,el, parent) { 
  var elmt = document.createElementNS(SVG_NS, el);
  for (var name in o) {
    if (o.hasOwnProperty(name)) {
      elmt.setAttributeNS(null, name, o[name]);
    }
  }
  parent.appendChild(elmt);
  return elmt;
}
*{margin:0;padding:0;}
#wrap {
  height: auto;
  position: relative;
}
.test {
  width: 150px;
  height: 150px;
  position: absolute;
}

#square{background: gold;left: 120px;
  top: 230px;}

#circle{background:red;left: 150px;
  top: 270px;border-radius:50%;}

svg {
  border: 1px solid;
  position: absolute;
}
<div id="wrap">
<div id="square" class="test"></div>
<div id="circle" class="test"></div>
<svg id="svg" viewBox="0 0 100 500">
  <clipPath id="_clip">
          
  </clipPath>  
</svg>
</div>


推荐阅读