You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@angular/google-maps新增标记时实现聚合簇与标记一致的动画效果

Angular谷歌地图标记聚合簇动画实现方案

基础信息

  • 依赖版本:@angular/google-maps: 13.3.4
  • 需求:新增地图标记时,标记聚合簇与普通独立标记保持一致的DROP下落动画效果

原有问题代码

组件模板(app.component.html)

<google-map height="400px"
            width="750px"
            [center]="center"
            [zoom]="zoom"
            >
  <map-marker-clusterer [zoomOnClick]="true" [imagePath]="markerClustererImagePath">
    <map-marker *ngFor="let markerPosition of markerPositions"
                [options]="markerOptions"
                [position]="markerPosition"
    ></map-marker>
  </map-marker-clusterer>
</google-map>

<button (click)="addSingleMarker($event)">Add new Marker</button>

<button (click)="addMarkerToCluster($event)">Add new Cluster</button>

组件逻辑(app.component.ts)

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  center = { lat: 24, lng: 12 };
  zoom = 4;

  markerPositions = [
    { lat: 24, lng: 12 },
    { lat: 24, lng: 12 },
    { lat: 15, lng: 6 },
  ];

  markerOptions: google.maps.MarkerOptions = {
    animation: google.maps.Animation.DROP
  };

  markerClustererImagePath =
    'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m';

  public addMarkerToCluster($event: google.maps.MapMouseEvent) {
    if ($event.latLng !== null) {
      this.markerPositions.push({ lat: 24, lng: 12 });
    }
  }

  public addSingleMarker($event: google.maps.MapMouseEvent) {
    if ($event.latLng !== null) {
      this.markerPositions.push({ lat: 21, lng: 2 });
    }
  }
}

实现步骤

默认的map-marker-clusterer没有内置簇图标更新时的动画逻辑,当前给普通map-marker配置的DROP动画只会作用于独立标记,不会作用于聚合生成的簇图标,按以下步骤修改即可:

  • 获取聚合簇实例
    给模板中的聚合簇组件添加模板引用变量,通过ViewChild在组件类中拿到实例:
    模板部分修改聚合簇标签:
    <map-marker-clusterer #clusterer [zoomOnClick]="true" [imagePath]="markerClustererImagePath">
    
    组件类新增依赖引入和实例声明:
    import { ViewChild } from '@angular/core';
    import { MapMarkerClusterer } from '@angular/google-maps';
    
    export class AppComponent {
      // 其他原有属性保留
      @ViewChild('clusterer') clusterer!: MapMarkerClusterer;
    }
    
  • 绑定簇渲染事件,手动添加动画
    在ngAfterViewInit生命周期中监听聚合完成事件,每次簇重绘时给新生成的簇标记设置DROP动画,增加判断避免重复触发已有簇的动画:
    import { AfterViewInit } from '@angular/core';
    
    export class AppComponent implements AfterViewInit {
      // 其他原有属性保留
    
      ngAfterViewInit(): void {
        this.clusterer.clustererInstance.addListener('clusteringend', () => {
          this.clusterer.clusters.forEach(cluster => {
            // 访问簇内部的标记实例,TS类型报错可加@ts-ignore忽略,不影响运行
            // @ts-ignore
            const clusterMarker = cluster.clusterIcon_.marker_;
            if (!clusterMarker.getAnimation()) {
              clusterMarker.setAnimation(google.maps.Animation.DROP);
            }
          })
        })
      }
    }
    
  • 修复新增标记的逻辑bug
    原有代码中绑定到普通button点击事件的方法,入参是按钮点击事件而非地图鼠标事件,不存在latLng属性,会导致点击按钮无法新增标记。同时直接push数组在OnPush变更检测模式下不会触发视图更新,替换为返回新数组的写法:
    public addMarkerToCluster() {
      // 可替换为实际业务需要的聚合点坐标
      this.markerPositions = [...this.markerPositions, { lat: 24, lng: 12 }];
    }
    
    public addSingleMarker() {
      // 可替换为实际业务需要的独立标记坐标
      this.markerPositions = [...this.markerPositions, { lat: 21, lng: 2 }];
    }
    

补充:如果需要调整动画时长,可以在设置动画后加延时手动清除动画状态,避免动画效果残留。

内容的提问来源于stack exchange,提问作者Veronika89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 21:27:18