微信小程序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()
  }
})
相关推荐
蓝帆傲亦5 小时前
支付宝小程序性能暴增秘籍:UniApp项目极限优化全攻略
小程序·uni-app
CHU7290359 小时前
淘宝扭蛋机抽盒小程序前端功能解析:解锁趣味抽盒新体验
前端·小程序
2501_9339072111 小时前
深圳本凡科技专业企业APP开发,助力手机应用创新优化
科技·微信小程序·小程序
每天都要加油呀!12 小时前
TypeError: uni.requestPayment is not a function
小程序
java1234_小锋13 小时前
分享一套优质的微信小程序校园志愿者系统(SpringBoot后端+Vue3管理端)
微信小程序·小程序·校园志愿者
2501_9160088914 小时前
深入解析iOS机审4.3原理与混淆实战方法
android·java·开发语言·ios·小程序·uni-app·iphone
打破砂锅问到底00714 小时前
AI 驱动开发实战:10分钟从零构建「微信群相册」小程序
人工智能·微信·小程序·ai编程
CHU72903515 小时前
扭蛋机盲盒小程序前端功能设计解析:打造趣味与惊喜并存的消费体验
前端·小程序
QT.qtqtqtqtqt15 小时前
uni-app小程序前端开发笔记(更新中)
前端·笔记·小程序·uni-app
CHU72903517 小时前
直播商城APP前端功能全景解析:打造沉浸式互动购物新体验
java·前端·小程序