javascript - 填充重叠的圆形区域

标签 javascript jquery html css

我有两个相交的圆,我想让相交区域有颜色,即使这两个圆是透明的。我以为我可以找到一些方法来使用 css mix-blend-mode 属性来做到这一点,但我没有成功。

当然,我可以让圆圈有颜色并降低它们的不透明度,但我希望它们是白色或透明的,只有重叠区域才会有背景色。

我希望交叉区域能够动态变化,因为一个圆圈会跟随鼠标。 这是 codepen为此。

我不确定从哪里开始,如果 css 有一些技术,或者是否必须使用 jquery 来完成。

$(document).mousemove(function(e) { 

  $('.cursor').eq(0).css({
    left: e.pageX - 25,
    top: e.pageY - 20
  });

  // circles
  var c1 = $('.cursor');
  var c2 = $('.circle');
  
  // radius
  var d1 = c1.outerWidth(true)/2;
  var d2 = c2.outerWidth(true)/2;
  
  // centers of first circle
  var x1 = c1.offset().left + c1.width()/2;  
  var y1 = c1.offset().top + c1.height()/2;
  
  // centers of second circle
  var x2 = c2.offset().left + c2.width()/2;
  var y2 = c2.offset().top + c2.height()/2;
  
  var i1 = c2.find('.inter1');
  var i2 = c2.find('.inter2');
  var o = c1.find('.overlap');
  
  function calc() {
    var a = d2;
    var b = d1;
    var c = Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    var d = (b*b+c*c-a*a)/(2*c);
    var h = Math.sqrt((b*b) - (d*d));
    if (d < 0 || $.isNumeric(h)) {
      c2.css('border-color', 'red');
    } else {
      c2.css('border-color', 'black');
    }
    var x3 = (x2-x1)*d/c + (y2-y1)*h/c +  x1;
    var y3 = (y2-y1)*d/c - (x2-x1)*h/c +  y1;
    var x4 = (x2-x1)*d/c - (y2-y1)*h/c +  x1;
    var y4 = (y2-y1)*d/c + (x2-x1)*h/c +  y1;
    
    if ($.isNumeric(h)) {
      i1.show();
      i2.show();
    } else {
      i1.hide();
      i2.hide();
    }
    i1.offset({ top: y3-5, left: x3-5});
    i2.offset({ top: y4-5, left: x4-5});
  } calc();
  
  
});
body {
  background: #fff;
}

.overlap {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.5);
}

.cursor {
  height: 50px;
  width: 50px;
  border-radius: 50%;
  position: absolute;
  pointer-events: none;
  z-index: 999;
  border: 1px solid black;
  outline: 1px solid #c9d3ff;
  overflow: none;
}

.circle {
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 200px;
  height: 200px;
  border: 1px solid black;
  outline: 1px solid #c9d3ff;
}

.circle::after,
.cursor::after {
  display: block;
  content: '';
  height: 1px;
  background: #c9d3ff;
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
}

.circle::before,
.cursor::before {
  display: block;
  content: '';
  width: 1px;
  background: #c9d3ff;
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
}

.inter {
  width: 10px;
  height: 10px;
  background: black;
  border-radius: 50%;
  position: absolute;
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="cursor">
</div>

<div class="circle">
  <div class="inter1 inter"></div>
  <div class="inter2 inter"></div>
  <div>

最佳答案

解决此问题的一种方法是在主圆圈内添加一个“内部光标”圆圈。基于鼠标的移动,它会随着主光标一起移动,从而产生重叠的错觉。

在这种情况下,相交圆的背景颜色无关紧要。此外,您不必担心混合混合模式,因为内部光标具有背景颜色并且是隐藏的。仅当鼠标悬停在主圆上时才能查看。

看这个例子:

$(document).mousemove(function(e) {

  // elements
  let cursor = $('.cursor');
  let innerCursor = $('.inner-cursor');
  let c2 = $('.circle');

  let pos = {
    left: e.pageX - 25,
    top: e.pageY - 20
  };
  cursor.css(pos);

  innerCursor.css({
    left: pos.left - c2.offset().left,
    top:  pos.top - c2.offset().top
  });

  // circles


  // radius
  var d1 = cursor.outerWidth(true) / 2;
  var d2 = c2.outerWidth(true) / 2;

  // centers of first circle
  var x1 = cursor.offset().left + cursor.width() / 2;
  var y1 = cursor.offset().top + cursor.height() / 2;

  // centers of second circle
  var x2 = c2.offset().left + c2.width() / 2;
  var y2 = c2.offset().top + c2.height() / 2;

  var i1 = c2.find('.inter1');
  var i2 = c2.find('.inter2');
  var o = cursor.find('.overlap');

  function calc() {
    var a = d2;
    var b = d1;
    var c = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    var d = (b * b + c * c - a * a) / (2 * c);
    var h = Math.sqrt((b * b) - (d * d));
    // console.log(a, b, c, d, h);
    if (d < 0 || $.isNumeric(h)) {
      c2.css('border-color', 'red');
    } else {
      c2.css('border-color', 'black');
    }
    var x3 = (x2 - x1) * d / c + (y2 - y1) * h / c + x1;
    var y3 = (y2 - y1) * d / c - (x2 - x1) * h / c + y1;
    var x4 = (x2 - x1) * d / c - (y2 - y1) * h / c + x1;
    var y4 = (y2 - y1) * d / c + (x2 - x1) * h / c + y1;

    if ($.isNumeric(h)) {
      i1.show();
      i2.show();
    } else {
      i1.hide();
      i2.hide();
    }
    i1.offset({
      top: y3 - 5,
      left: x3 - 5
    });
    i2.offset({
      top: y4 - 5,
      left: x4 - 5
    });
  }
  calc();

});
body {
  background: #fff;
}

.clip {
  display: inline-block;
  background: blue;
  height: 50px;
  width: 50px;
  border-radius: 50%;
  clip-path: ellipse(50px 50px at 50% 0%);
  position: absolute;
  left: 750px;
  top: 40px;
}

.cursor {
  left: 750px;
  top: 40px;
}

.cursor {
  height: 50px;
  width: 50px;
  border-radius: 50%;
  position: absolute;
  pointer-events: none;
  z-index: 999;
  border: 1px solid black;
  outline: 1px solid #c9d3ff;
  overflow: none;
  mix-blend-mode: multiply;
  background: rgba(100, 100, 100, 0.1);
}

.circle {
  background: rgba(100, 100, 100, 0.1);
  border-radius: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 200px;
  height: 200px;
  border: 1px solid black;
  outline: 1px solid #c9d3ff;
  overflow: hidden;
}

.circle::after,
.cursor::after {
  display: block;
  content: '';
  height: 1px;
  background: #c9d3ff;
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
}

.circle::before,
.cursor::before {
  display: block;
  content: '';
  width: 1px;
  background: #c9d3ff;
  position: absolute;
  left: 50%;
  top: 0;
  bottom: 0;
}

.inter {
  width: 10px;
  height: 10px;
  background: black;
  border-radius: 50%;
  position: absolute;
  display: none;
}

.inner-cursor {
  height: 50px;
  width: 50px;
  border-radius: 50%;
  position: absolute;
  pointer-events: none;
  background: green;
  left: 50%;
  top: 50%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="cursor">

</div>
<span class="clip"></span>

<div class="circle">
  <div class='inner-cursor'></div>
  <div class="inter1 inter"></div>
  <div class="inter2 inter"></div>
</div>

关于javascript - 填充重叠的圆形区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57665335/

相关文章:

javascript - Accordion 菜单如何使所有类别都展开? - JQuery Accordion 菜单

javascript - 当多个 API 调用时只运行一次响应拦截器

javascript - 可以在 proptype 形状中使用默认值吗?

Javascript代码分析器开源代码或插件

javascript - 为多个操作创建 ASCX 控件

html - 固定宽度容器内的行内 block 元素

javascript - webpack 的 package.json 解析错误

javascript - 如何检索已解析的 url

javascript - 使用 jquery 操作选择框

css - 将 ul 对齐到固定 div 中的底部