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);
相关推荐
JIngJaneIL19 分钟前
助农惠农服务平台|助农服务系统|基于SprinBoot+vue的助农服务系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·助农惠农服务平台
云外天ノ☼24 分钟前
待办事项全栈实现:Vue3 + Node.js (Koa) + MySQL深度整合,构建生产级任务管理系统的技术实践
前端·数据库·vue.js·mysql·vue3·koa·jwt认证
一位搞嵌入式的 genius28 分钟前
前端实战开发(三):Vue+Pinia中三大核心问题解决方案!!!
前端·javascript·vue.js·前端实战
塞纳河畔的歌28 分钟前
保姆级教程 | 麒麟系统安装Edge浏览器
前端·edge
多睡觉觉30 分钟前
数据字典:从"猜谜游戏"到"优雅编程"的奇幻之旅
前端
嗝屁小孩纸33 分钟前
开发集成热门小游戏(vue+js)
前端·javascript·vue.js
赛博切图仔38 分钟前
深入理解 package.json:前端项目的 “身份证“
前端·javascript
UIUV41 分钟前
JavaScript 学习笔记:深入理解 map() 方法与面向对象特性
前端·javascript·代码规范
太平洋月光1 小时前
MJML邮件如何随宽度变化动态切换有几列📮
前端·css
AAA不会前端开发1 小时前
TypeScript核心类型系统完全指南
前端·typescript