<style>
    *{
      margin: 0;
      padding: 0;
    }
    svg{
      background: aliceblue;
    }
</style>
  <!-- <h1>点击屏幕,查看是否在多边形内</h1> -->
  <svg xmlns="http://www.w3.org/2000/svg" width="800px" height="500px" viebox="0 0 400 400">

    <!-- <polygon id="polygon" points="160,120 200,140 200,180 160,200 120,180 120,140" fill="red"/> -->

    <!-- <polygon id="polygon" points="220,10 300,210 170,250 123,234" fill="lime"/> -->

    <!-- <polygon id="polygon" points="100,10 40,180 190,60 10,60 160,180" style="fill:lime;" title="不要惊慌,这个五角星⭐️的线重合了,所以检测不出来" /> -->

    <!-- <polygon id="polygon" points="50,350 100,50 350,400" fill="red"></polygon> -->

    <!-- <polygon id="polygon" points="50,350 50,50 350,350" fill="red"></polygon> -->

    <polygon id="polygon" points="225 250 380 210 485 280 460 355 290 420 190 330 165 285 180 230 245 300 385 295 425 295 415 265" fill="pink"></polygon>

  </svg>
  
  <script>

    var polygon = document.getElementById('polygon')
    var points = polygon.points
    var newPoints = []
  
    for(var i = 0; i < points.length; i++) {
      newPoints.push({
        x: points.getItem(i).x,
        y: points.getItem(i).y
      })
    }
  
    document.addEventListener('click', function(e){

      // console.log(e)
      var clickPosition = {
        x: e.pageX,
        y: e.pageY
      }

      isPointInPolygon(clickPosition, newPoints)
    }, false)

    function isPointInPolygon(p, poly) {
      var dotX = p.x, dotY = p.y, count = 0, x, y;
      var inStr = 'in', outStr = 'out';
  
      for(var i = 0, length = poly.length, j = length - 1; i < length; j = i, i++) {
        var startX = poly[i].x, startY = poly[i].y, endX = poly[j].x, endY = poly[j].y;
  
        // 点与多边形顶点重合
        if((startX == dotX && startY == dotY) || (endX == dotX && endY == dotY)) return true;
        // if (i == 2) debugger
        
        // 射线为当前点往右坐标递增的水平线
        var gapX = endX - startX

        if (gapX == 0) { // 垂直坐标的情况
            x = startX
            y = dotY
        } else {
          var k = (endY - startY) / gapX
          var b = startY - k * startX

          if (k === 0 && b === dotY) {
            x = dotX
            y = b
          } else if (k === 0) {
            continue // 水平方向
          } else {
            x = (dotY - b) / k
            y = dotY
          }
        }
  
        var maxX = Math.max(startX, endX);
        var minX = Math.min(startX, endX);
  
        var maxY = Math.max(startY, endY);
        var minY = Math.min(startY, endY);
  
        if(x >= dotX && 
          y >= minY && y <= maxY &&
          x >= minX && x <= maxX ) {
          count++
          // console.log([dotX, dotY])
          console.log([x, y], [startX, startY], [endX, endY], i, count)
        }
      }
  
      // 射线穿过多边形边界的次数为奇数时点在多边形内
      if (count % 2 == 0 ) { // 偶数次
        console.log(outStr)
        alert(outStr)
        return false
      } else if(count >= 1) {
        console.log(inStr)
        alert(inStr)
        return true
      }
    }
</script>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.