微信小程序map组件聚合簇样式自定义

目标效果如下图

1、微信小程序原生语言开发

2、map组件聚合簇样式自定义

下面代码是我调研时候的调试数据,可做demo参考。

html 复制代码
<map
  id="myMap"
  style="width: 100%; height: 100vh;"
  latitude="40.22429"
  longitude="116.43639"
  scale="{{scale}}"
>
</map>
javascript 复制代码
const app = getApp();
Page({
  data: {
    scale: 16,
    markers: []
  },

  onReady() {
    const _this = this;
    this.mapCtx = wx.createMapContext('myMap', this); // 绑定this
    this.mapCtx.initMarkerCluster({
      gridSize: 50,              // 必须:聚合网格大小(像素,控制marker距离多近会聚合)
      minClusterSize: 2,         // 必须:最小聚合数量(默认2,即≥2个marker才会聚合)
      maxZoom: 20,               // 必须:超过该缩放级别后不聚合
      enableDefaultStyle: false, // 禁用默认聚合样式,使用自定义
      clusterMarker: {
        iconPath: '/image/abc.png',  // 网络图标记得在 downloadFile 合法域名中
        width: 64,                   // 图片尺寸最好和实际图片一致
        height: 64,
        anchor: { x: 0.5, y: 0.5 },
        zIndex: 999,                 // 提高层级,确保在普通标记上方
      },
      success(res) {
        _this.addMarkersToMap()
      },
      fail(err) {}
    });

  },
  // 监听聚合创建事件,兜底处理自定义聚合样式
  markerClusterCreateFn(){
    const _this = this;
    this.mapCtx.on('markerClusterCreate', (res) => {
      const clusters = res.clusters;
      const clusterMarkers = clusters.map(cluster => {
        const { center, clusterId, markerIds } = cluster;
        const count = markerIds.length; // 聚合点数量
        // 1. 找到聚合簇中第一个点位的完整信息(通过markerId匹配)
        const firstMarker = _this.data.markers.find(marker => marker.id === markerIds[0]);
        // 2. 提取第一个点位的label.content,没有则用默认文本
        const firstContent = firstMarker?.label?.content || '多个点位';
        // 3. 拼接聚合簇标题:第一个内容+...等X个
        const calloutContent = `${firstContent}...等`;
        return {
          ...center,
          clusterId, // 必须携带clusterId,确保聚合关联
          iconPath: '/image/abc.png',
          width: 64,
          height: 64,
          anchor: { x: 0.5, y: 0.5 },
          label: { // 聚合簇的自定义图标样式
            content: String(count), // 显示聚合数量
            color: '#900', // 文字颜色(白色更醒目)
            fontSize: 14, // 文字大小
            fontWeight: 'bold', // 文字加粗
            anchorX: 0.5, // 文字X轴锚点(居中)
            anchorY: 0.5, // 文字Y轴锚点(居中)
            bgColor: 'transparent', // 文字背景透明,避免遮挡图标
            padding: 2 // 文字内边距,优化显示
          },
          // callout 显示标题(聚合簇图标上方,可点击显示或常驻)
          callout: {
            content: calloutContent, // 自定义标题
            color: '#333',
            fontSize: 12,
            bgColor: '#fff', // 白色背景突出标题
            borderRadius: 4,
            padding: 4,
            display: 'ALWAYS', // 一直显示(可选 BYCLICK 点击显示)
            textAlign: 'center',
            anchorX: 0.5,
            anchorY: -1.2 // 标题在图标上方
          }
        };
      });
      // 添加自定义聚合标记
      if (clusterMarkers.length > 0) {
        this.mapCtx.addMarkers({
          markers: clusterMarkers,
          clear: false,
          success: () => {}
        });
      }
    });
  },
  addMarkersToMap(){
    const _this = this;
    // 标记点数组,方便调试的固定假数据
    const markersAll = [
      { id: 20, latitude: 40.22429, longitude: 116.43639,
        iconPath: '/image/orderSel.png',
        label:{
          anchorX: 8,
          anchorY: -25,
          bgColor: "#fff",
          borderRadius: 30,
          color: "#F09834",
          content: "礼物手工",
          fontSize: 11,
          padding: 2,
        },
        width: 34, height: 48, joinCluster: true, anchor: { x: 0.5, y: 1 } },
      { id: 21, latitude: 40.22429, longitude: 116.43629,
        iconPath: '/image/orderSel.png',
        label:{
          anchorX: 8,
          anchorY: -25,
          bgColor: "#fff",
          borderRadius: 30,
          color: "#F09834",
          content: "南山春日感官",
          fontSize: 11,
          padding: 2,
        },
        width: 34, height: 48, joinCluster: true, anchor: { x: 0.5, y: 1 } },
      { id: 23, latitude: 40.22429, longitude: 116.43659,
        iconPath: '/image/orderSel.png',
        label:{
          anchorX: 8,
          anchorY: -25,
          bgColor: "#fff",
          borderRadius: 30,
          color: "#F09834",
          content: "木作师资课",
          fontSize: 11,
          padding: 2,
        },
        width: 34, height: 48, joinCluster: true, anchor: { x: 0.5, y: 1 } },
    ]
    // 调用 addMarkers 添加
    this.mapCtx.addMarkers({
      markers: markersAll,
      clear: false,
      success: () => {
        console.log('标记添加成功');
      },
      fail: (err) => {
        console.error('标记添加失败', err);
      },
      complete: (e) => {
        console.log('标记添加成功或者失败都会触发', e);
      }
    })
    this.setData({
      markers: markersAll
    })
    _this.markerClusterCreateFn()
  }
})
相关推荐
菠菠萝宝4 小时前
【AI应用探索】-10- Cursor实战:小程序&APP - 下
人工智能·小程序·kotlin·notepad++·ai编程·cursor
qq_12498707534 小时前
基于微信小程序的茶叶茶具销售和管理系统(源码+论文+部署+安装)
微服务·微信小程序·小程序·毕业设计
CDwenhuohuo4 小时前
微信小程序里用 setData() 修改数据并打印输出 的几种写法
javascript·微信小程序·小程序
小明记账簿10 小时前
微信小程序开发实战:图片转 Base64 全解析
微信小程序·小程序
汤姆yu10 小时前
基于微信小程序的粤语文化传播系统
微信小程序·小程序
Q_Q51100828510 小时前
python+uniapp基于微信小程序的垃圾分类信息系统
spring boot·python·微信小程序·django·flask·uni-app·node.js
ducaifeng8610 小时前
微信小程序:onReady详解
微信小程序·小程序
李纲明11 小时前
开发一个小程序花多少钱
微信小程序·wordpress·wordpress外贸站
_jeneen12 小时前
小程序 scroll-view 触底事件不触发问题
微信小程序·小程序