经纬志
首页 / MapLibre / API 文档

StyleImageInterface

先看结论

动态图标的约定接口:给 addImage 传一个带像素数组与 render 方法的对象,图标就能逐帧变化。

最后验证 2026-11-03 · MapLibre GL JS 4.x · 更新 2026-10-29 · 引用本文
interface StyleImageInterface = { width, height, data, render?, onAdd?, onRemove? }

它是实现约定,不是可导入的类。普通对象只要字段齐全就能用。

字段

字段说明
width图像宽度,像素
height图像高度,像素
dataRGBA 顺序的像素数据,长度必须为 width × height × 4;也可传 WebGL 数据回调
render(map?)每帧在图标被使用前调用,返回 true 表示像素已更新
onAdd(map, id)图标加入地图时调用,可在这里保存地图引用
onRemove()图标被移除时调用,用来停掉定时器与清理资源

呼吸灯效果

var SIZE = 48;

var pulse = {
  width: SIZE,
  height: SIZE,
  data: new Uint8Array(SIZE * SIZE * 4),

  onAdd: function (map) {
    this.map = map;
    this.start = performance.now();
  },

  render: function () {
    var t = (performance.now() - this.start) / 1000;
    var alpha = 0.35 + 0.35 * Math.sin(t * 2.4);
    var r = SIZE / 2 - 2;

    for (var y = 0; y < SIZE; y++) {
      for (var x = 0; x < SIZE; x++) {
        var dx = x - SIZE / 2;
        var dy = y - SIZE / 2;
        var inside = dx * dx + dy * dy <= r * r;
        var i = (y * SIZE + x) * 4;

        this.data[i] = 31;
        this.data[i + 1] = 95;
        this.data[i + 2] = 208;
        this.data[i + 3] = inside ? Math.round(alpha * 255) : 0;
      }
    }

    this.map.triggerRepaint();
    return true;
  },

  onRemove: function () {
    this.map = null;
  }
};

map.addImage('pulse', pulse);

data 的每个像素占四个字节,索引按行优先递增。 透明度写第四个字节,圆形之外置 0,否则图标会是一个实心方块。

何时返回 true

render 返回 true 才把新像素提交到图标表。 每帧都返回真会让地图持续重绘,CPU 与显存带宽都被占满; 内容没变时返回 false,动画只在需要时推进。

播放一次就停的动画可以在结束时不再调用 triggerRepaint, 地图随即回到 idle 状态,事件循环有空闲处理其它任务。

在图层里引用

map.addLayer({
  id: 'pulse-layer',
  type: 'symbol',
  source: 'poi',
  layout: {
    'icon-image': 'pulse',
    'icon-size': 0.6,
    'icon-allow-overlap': true
  }
});

与逐帧 updateImage 的选择

方式开销适用
StyleImageInterface每帧一次 CPU 像素写入与上传持续动画、每帧都变
map.updateImage调用时上传一次低频更新、事件驱动变化

render 里不要画 Canvas。 接口要的是像素数组,不是绘制指令。需要 Canvas 绘制能力时, 先在离屏 Canvas 上画好,再 getImageData 拷进 data; 但每帧拷贝成本更高,能直接算像素就别用 Canvas。

引用本文

经纬志(2026)。《StyleImageInterface》。https://www.jingweizhi.com/maplibre/api/style-image-interface.html(访问日期 2026-11-03)。