评论

在map地图上拖动绘制四边形

在map地图上拖动绘制四边形

想在小程序地图上手动拖动绘制四边形,选中marker,找了好久没发现有相关的,自己做了一个,供大家参考,有更优的方法欢迎大家一起交流学习。

以下是WXML代码

<map id="myMap" wx:key="id" longitude="{{114.142856}}" latitude="{{33.580852}}" scale="{{scale}}" markers="{{markers}}" bindmarkertap="markerTap" bindcallouttap="markerTap" bindlabeltap="markerTap" show-compass enable-poi="{{true}}" bindregionchange="closeDig" polygons="{{polygons}}" enable-scroll="{{!isDraw}}">
   
    <!-- 绘图 -->
    <canvas wx:if="{{isDraw}}" type="2d" id="myCanvas" style="width: 100%;height: 100%;" catch:touchstart="canvasTouch" catch:touchmove="canvasTouch" catch:touchend="canvasTouch" />
</map>


js代码

//绘制
  showDraw() {
    this.setData({
      isDraw: true,
    });
    if (this.data.polygons.length == 0)
      wx.showToast({
        title: "请在地图上拖动进行框选",
        icon: "none",
      });
    //获取myCanvas
    if (1) {
      const query = wx.createSelectorQuery();
      query
        .select("#myCanvas")
        .fields({ node: true, rect: true, size: true })
        .exec((res) => {
          this.canvas = res[0];
          const canvas = res[0].node;
          const ctx = canvas.getContext("2d");
          const dpr = wx.getSystemInfoSync().pixelRatio;
          canvas.width = res[0].width * dpr;
          canvas.height = res[0].height * dpr;
          ctx.scale(dpr, dpr);
        });
    }
  },
  //绘制四边形
  canvasTouch(e) {
    let _this = this;
    let context = this.canvas.node.getContext("2d");
    let isDrawing = false;
    let currentRect = this.currentRect;
    //获取canvas
    const x = e.changedTouches[0].clientX;
    const y = e.changedTouches[0].clientY - this.canvas.top;


    //开始
    if (e.type == "touchstart") {
      isDrawing = true;
      this.currentRect = {
        x: x,
        y: y,
        startX: x,
        startY: y,
      };
    }
    //绘制
    if (e.type == "touchmove") {
      currentRect.width = Math.abs(x - currentRect.startX);
      currentRect.height = Math.abs(y - currentRect.startY);
      if (x < currentRect.startX) currentRect.x = x;
      if (y < currentRect.startY) currentRect.y = y;
      redraw();
    }
    //结束
    if (e.type == "touchend") {
      let list = [];
      outputXY().map((i) => {
        this.MapContext.fromScreenLocation({
          x: i[0],
          y: i[1],
          success(res) {
            list.push({
              latitude: res.latitude,
              longitude: res.longitude,
            });
            //新增
            if (list.length > 3) {
              _this.setData({
                isDraw: false,
                polygons: [
                  ..._this.data.polygons,
                  {
                    points: list,
                    strokeWidth: 2,
                    strokeColor: "#18FFFF",
                    fillColor: "#18FFFF40",
                    // zIndex: 999,
                  },
                ],
              });
              _this.isBoxSelection();
            }
          },
        });
      });
    }
    function outputXY() {
      const c = currentRect;
      // 计算角度
      let angle = (Math.atan2(y - c.startY, x - c.startX) * 180) / Math.PI;
//修复ios地图位置xy坐标偏移的问题
      if (wx.getDeviceInfo().platform == "ios") {
        const wi = wx.getWindowInfo();
        const h = wi.screenTop + _this.canvas.top;
        c.startY = c.startY + h;
      }
      // 左上右下
      if (angle > 0 && angle < 90) {
        return [
          [c.startX, c.startY],
          [c.startX + c.width, c.startY],
          [c.startX + c.width, c.startY + c.height],
          [c.startX, c.startY + c.height],
        ];
        // 右上左下
      } else if (angle > 90 && angle < 180) {
        return [
          [c.startX, c.startY],
          [c.startX - c.width, c.startY],
          [c.startX - c.width, c.startY + c.height],
          [c.startX, c.startY + c.height],
        ];
        // 左下右上
      } else if (angle < 0 && angle > -90) {
        return [
          [c.startX, c.startY],
          [c.startX, c.startY - c.height],
          [c.startX + c.width, c.startY - c.height],
          [c.startX + c.width, c.startY],
        ];
        // 右下左上
      } else if (angle < -90 && angle > -180) {
        return [
          [c.startX, c.startY],
          [c.startX - c.width, c.startY],
          [c.startX - c.width, c.startY - c.height],
          [c.startX, c.startY - c.height],
        ];
      }
    }
    //绘制矩形
    function redraw() {
      context.clearRect(00, _this.canvas.width, _this.canvas.height);
      if (currentRect) {
        // 设置边框的粗细
        context.lineWidth = 2;
        // 设置边框颜色
        context.strokeStyle = "#18FFFF";
        // 绘制边框
        context.strokeRect(
          currentRect.x,
          currentRect.y,
          currentRect.width,
          currentRect.height
        );
      }
    }
  },


最后一次编辑于  2024-06-17  
点赞 3
收藏
评论

2 个评论

  • 富贵
    富贵
    2024-11-01

    请问楼主这个插件的应用场景是什么?

    2024-11-01
    赞同
    回复
  • 冲冲
    冲冲
    2024-06-19

    哥 ,请问一下 公众号可以这样用吗

    2024-06-19
    赞同
    回复 1
    • Ming
      Ming
      2024-06-19
      公众号我没试过
      2024-06-19
      回复
登录 后发表内容