openlayer实现定位闪烁

一、项目介绍

产品说地图上只标一个图标,有点看不清在哪里,不够明显,行吧,那我给你加个动画,现在可以看清楚了吧。

二、初始化地图

初始化一个高德地图并定义一个矢量图层,用来展示矢量图标。

js 复制代码
//高德地图
this.raster = new TileLayer({
    source: new XYZ({
     url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=2&style=6",
     }),
 });
 //矢量图层
 this.source = new VectorSource({ wrapX: false });
 this.vector = new VectorLayer({
      source: this.source,
      zIndex: 100,
      declutter: true  // 避免图标重叠
 });
 
 //初始化地图
 this.map = new Map({
  layers: [this.raster, this.vector],
  target: id,
  view: new View({
    center: fromLonLat(this.center),
    zoom: 13,
  }),
  controls: [], // 不添加任何默认控件
});

三、创建矢量图标

然后引入icon类型,创建一个icon图标。

方法类别 核心类/API 优点 适用场景 关键提示
图片图标 ol/style/Icon 简单直接,支持多种图片格式 使用静态图片(PNG, JPG, SVG等)作为图标 注意调整锚点(anchor)以确保精准定位
字体图标 (Canvas) ol/style/Icon + Canvas 可动态生成,灵活修改颜色样式 需要动态控制颜色、大小的图标 将Canvas转换为DataURL使用
字体图标 (Text) ol/style/Text 无需图片,使用字体文件,矢量缩放清晰 使用iconfont等字体图标库 确保字体文件正确加载,处理Unicode编码
矢量图形 ol/style/RegularShape 由代码生成,无需外部资源,可动态设置样式 简单几何形状(圆形、方形、星形等) 可组合使用多种Style实现复杂效果
js 复制代码
//feacture图形
 const iconFeature = new Feature({
      geometry: new Point(fromLonLat([item.lon,item.lat])),
      name: item?.name,
      id: item?.id,
      type: "icon",
      description: description,
      item: item,
      population: 4000,
      rainfall: 500,
  });
  //样式
 const iconStyle = new Style({
      image: new Icon({
        anchor: [0.5, 0.5],
        scale: 0.4,
        src: url,
      }),
      text: new Text({
        text: iconFeature.get("name"),
        textAlign: "center",
        textBaseline: "middle",
        offsetY: 30, // 文字向下偏移
        font: "bold 14px Calibri,sans-serif",
        fill: new Fill({
          color: "#333",
        }),
        stroke: new Stroke({
          color: "#fff",
          width: 1,
        }),
      }),
    });

    iconFeature.setStyle(iconStyle);
    this.source.addFeature(iconFeature);

四、闪烁图标

OpenLayers 提供了多种图层事件监听函数,允许你监测图层的状态变化、用户交互以及渲染过程。

事件类型 主要事件名称 说明 适用场景
图层状态事件 loadstart, loadend 监听图层数据的开始加载和加载完成状态 显示加载进度条、处理加载异常
visibilitychanged 图层可见性改变时触发 同步控制其他图层显示隐藏、动态调整界面元素
图层操作事件 addlayer, removelayer 图层被添加到地图或从地图移除时触发 (注:这些是地图的事件,而非图层自身的事件) 维护图层列表、记录用户操作日志
渲染相关事件 prerender, postrender 在图层渲染前后触发 进行自定义绘制(如绘制遮罩、高亮)、性能监控
precompose, postcompose 在整个地图合成前后触发 (更像是地图上下文的事件) 高级效果处理(如滤镜)、地图截图
矢量图层交互事件 featureselected, featureunselected 使用 Select 交互时,要素被选中或取消选中时触发 显示弹出Popup、展示属性信息、执行自定义操作
图层变动事件 change, change:source, propertychange 图层属性(如源source)或样式发生变化时触发 响应式更新UI、动态调整地图行为

OpenLayers 中的 postrender 事件是一个非常重要的图层渲染事件,它在图层每一帧的渲染完成后触发。你可以利用这个事件在现有的图层渲染之上执行自定义的绘制操作、创建动画效果或进行后处理。

js 复制代码
 let radius = 20;

 this.vector.on("postrender", listerEvent );
 
 function listerEvent(evt){
      const features = this.source.getFeatures();
      if (radius >= 50) radius = 20;
      var opacity = (50 - radius) * (1 / 50); //不透明度
      var pointStyle = new Style({
        image: new CircleStyle({
          radius: radius,
          stroke: new Stroke({
            color: "rgba(35,143,196," + opacity + ")",
            width: 3 - radius / 50, //设置宽度
          }),
          offsetY: -20,
        }),
      });
      // 获取矢量要素上下文
      let vectorContext = getVectorContext(evt);
      vectorContext.setStyle(pointStyle);

      radius = radius + 0.3; //调整闪烁速度

      features.forEach((feature) => {
        if (feature.get("type") === "icon") {
          vectorContext.drawGeometry(feature.getGeometry());
        }
      });

      if (features.length) {
        this.map.render();
      }
    }
    

由于 postrender 事件在每一次图层渲染时都会触发(例如地图移动、缩放时),因此其回调函数的执行效率至关重要。

  1. 避免昂贵操作 :在回调函数中避免执行复杂的计算、大规模的 DOM 操作或频繁创建大量新对象(如复杂的样式 Style 或几何体 Geometry),否则极易造成页面卡顿。
  2. 及时清理 :当动画停止或不再需要监听 postrender 时,一定要使用 layer.un() 方法移除事件监听器,否则它会继续执行,浪费资源。
  3. 依赖 frameState :对于动画,利用 event.frameState.time 来计算动画状态,它可以提供一致的时间参考。
js 复制代码
//根据id删除矢量图标
 this.source.forEachFeature((feature) => {
  if (feature.get("id") === id) {
    this.source.removeFeature(feature);
  }
});
//移除监听
this.map.un("postrender",listerEvent);
相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax