微信小程序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()
  }
})
相关推荐
米饭同学i12 小时前
微信小程序实现动态环形进度条组件
前端·微信小程序
说私域15 小时前
基于AI智能名片链动2+1模式服务预约小程序的旅拍消费需求激发路径研究
大数据·人工智能·小程序
小白学大数据16 小时前
某程旅行小程序爬虫技术解析与实战案例
爬虫·小程序
小小王app小程序开发17 小时前
家政服务小程序特殊玩法开发全解析:技术实现+架构支撑+合规落地
小程序·架构
游戏开发爱好者817 小时前
2025年iOS应用上架App Store全指南,开发者必看
android·ios·小程序·https·uni-app·iphone·webview
集成显卡18 小时前
CVE检索工具 | 开发一款检索漏洞信息的小程序
网络安全·小程序·uni-app·cve·漏洞信息
luffy545918 小时前
微信小程序实现图片横向滑动的示例
微信小程序·小程序
万岳软件开发小城18 小时前
直播电商系统源码搭建直播带货APP/小程序的完整流程
小程序·php·软件开发·直播带货系统源码·直播电商app开发
棒棒的唐19 小时前
使用微信小程序版Vant的upload组件上传身份证的样式自定义方案(Css魔改版)
css·微信小程序·小程序
jaqi.l19 小时前
uni-app 小程序全局挂载分享功能,并动态配置页面是否可以分享
vue.js·小程序·uni-app