vue3-openlayers marker 光晕扩散(光环扩散)(postrender 事件和 render 方法)

本篇介绍一下使用 vue3-openlayers marker 光晕扩散(光环扩散)(postrender 事件和 render 方法)

1 需求

  • marker 光晕扩散(光环扩散)

2 分析

marker 光晕扩散(光环扩散)使用 postrender 事件和 render 方法

关于即时渲染的知识点请看上篇《openlayers marker 光晕扩散(光环扩散)(postrender 事件和 render 方法)》

3 实现

3.1 实现一(光环)

javascript 复制代码
<template>
  <ol-map
    :loadTilesWhileAnimating="true"
    :loadTilesWhileInteracting="true"
    style="width: 100%; height: 100%"
    ref="mapRef"
  >
    <ol-view ref="view" :center="center" :zoom="zoom" :projection="projection" />

    <ol-tile-layer>
      <ol-source-tianditu
        layerType="img"
        :projection="projection"
        :tk="key"
        :hidpi="true"
        ref="sourceRef"
      ></ol-source-tianditu>
    </ol-tile-layer>
    <ol-tile-layer>
      <ol-source-tianditu
        :isLabel="true"
        layerType="img"
        :projection="projection"
        :tk="key"
        :hidpi="true"
      ></ol-source-tianditu>
    </ol-tile-layer>
    <ol-vector-layer ref="vectorLayerRef" @postrender="handlePostRender">
      <ol-source-vector>
        <ol-feature>
          <ol-geom-point :coordinates="[110, 30]"></ol-geom-point>
          <ol-style>
            <ol-style-icon :src="iconSrc" :scale="0.05"></ol-style-icon>
          </ol-style>
        </ol-feature>
        <ol-feature>
          <ol-geom-point :coordinates="[112, 31]"></ol-geom-point>
          <ol-style>
            <ol-style-icon :src="iconSrc" :scale="0.05"></ol-style-icon>
          </ol-style>
        </ol-feature>
      </ol-source-vector>
    </ol-vector-layer>
  </ol-map>
  <div class="toolbar">
    <el-button type="primary" @click="handleClick">{{ animationFlag ? '停止' : '开始' }}</el-button>
  </div>
</template>

<script setup lang="ts">
import iconSrc from '@/assets/image/truck.png';
import { getVectorContext } from 'ol/render.js';
import { easeOut } from 'ol/easing.js';
import { Circle, Stroke, Style } from 'ol/style';

const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const mapRef = ref();
const key = '替换为天地图key';
const sourceRef = ref(null);
const vectorLayerRef = ref(null);
const animationFlag = ref(false);
const duration = ref([3000, 1000]);
const start = ref([0, 0]);

const handleClick = () => {
  if (!animationFlag.value) {
    start.value = start.value.map(i => Date.now());
    vectorLayerRef.value.vectorLayer.changed();
  }
  animationFlag.value = !animationFlag.value;
};

const handlePostRender = e => {
  if (animationFlag.value) {
    const time = e.frameState.time;
    vectorLayerRef.value.vectorLayer
      .getSource()
      .getFeatures()
      .forEach((f, idx) => {
        // 时间戳差(毫秒)
        let elapsedTime = time - start.value[idx];
        if (elapsedTime >= duration.value[idx]) {
          start.value[idx] = Date.now();
          elapsedTime = duration.value[idx];
        }
        // 获取矢量上下文
        const vectorContext = getVectorContext(e);
        // elapsedRatio值0到1之间
        const elapsedRatio = elapsedTime / duration.value[idx];
        const radius = easeOut(elapsedRatio) * 25 + 5;
        const opacity = easeOut(1 - elapsedRatio);

        const style = new Style({
          image: new Circle({
            radius: radius,
            stroke: new Stroke({
              color: 'rgba(255, 0, 0, ' + opacity + ')',
              width: 1 + opacity
            })
          })
        });
        // 将feature渲染到画布中。
        vectorContext.drawFeature(f.clone(), style);
      });
    mapRef.value.map.render();
  }
};
</script>
<style scoped lang="scss">
.toolbar {
  position: absolute;
  top: 20px;
  left: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

3.2 实现二(光晕)

javascript 复制代码
<template>
  <ol-map
    :loadTilesWhileAnimating="true"
    :loadTilesWhileInteracting="true"
    style="width: 100%; height: 100%"
    ref="mapRef"
  >
    <ol-view ref="view" :center="center" :zoom="zoom" :projection="projection" />

    <ol-tile-layer>
      <ol-source-tianditu
        layerType="img"
        :projection="projection"
        :tk="key"
        :hidpi="true"
        ref="sourceRef"
      ></ol-source-tianditu>
    </ol-tile-layer>
    <ol-tile-layer>
      <ol-source-tianditu
        :isLabel="true"
        layerType="img"
        :projection="projection"
        :tk="key"
        :hidpi="true"
      ></ol-source-tianditu>
    </ol-tile-layer>
    <ol-vector-layer ref="vectorLayerRef" @postrender="handlePostRender">
      <ol-source-vector>
        <ol-feature>
          <ol-geom-point :coordinates="[110, 30]"></ol-geom-point>
        </ol-feature>
        <ol-feature>
          <ol-geom-point :coordinates="[112, 31]"></ol-geom-point>
        </ol-feature>
      </ol-source-vector>
    </ol-vector-layer>
    <ol-vector-layer >
      <ol-source-vector>
        <ol-feature>
          <ol-geom-point :coordinates="[110, 30]"></ol-geom-point>
          <ol-style>
            <ol-style-icon :src="iconSrc" :scale="0.05"></ol-style-icon>
          </ol-style>
        </ol-feature>
        <ol-feature>
          <ol-geom-point :coordinates="[112, 31]"></ol-geom-point>
          <ol-style>
            <ol-style-icon :src="iconSrc" :scale="0.05"></ol-style-icon>
          </ol-style>
        </ol-feature>
      </ol-source-vector>
    </ol-vector-layer>
  </ol-map>
  <div class="toolbar">
    <el-button type="primary" @click="handleClick">{{ animationFlag ? '停止' : '开始' }}</el-button>
  </div>
</template>

<script setup lang="ts">
import iconSrc from '@/assets/image/truck.png';
import { getVectorContext } from 'ol/render.js';
import { easeOut } from 'ol/easing.js';
import { Circle, Fill, Stroke, Style } from 'ol/style';

const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const mapRef = ref();
const key = '替换为天地图key';
const sourceRef = ref(null);
const vectorLayerRef = ref(null);
const animationFlag = ref(false);
const duration = ref([3000, 1000]);
const start = ref([0, 0]);

const handleClick = () => {
  if (!animationFlag.value) {
    start.value = start.value.map(i => Date.now());
    vectorLayerRef.value.vectorLayer.changed();
  }
  animationFlag.value = !animationFlag.value;
};

const handlePostRender = e => {
  if (animationFlag.value) {
    const time = e.frameState.time;
    vectorLayerRef.value.vectorLayer
      .getSource()
      .getFeatures()
      .forEach((f, idx) => {
        // 时间戳差(毫秒)
        let elapsedTime = time - start.value[idx];
        if (elapsedTime >= duration.value[idx]) {
          start.value[idx] = Date.now();
          elapsedTime = duration.value[idx];
        }
        // 获取矢量上下文
        const vectorContext = getVectorContext(e);
        // elapsedRatio值0到1之间
        const elapsedRatio = elapsedTime / duration.value[idx];
        const radius = easeOut(elapsedRatio) * 25 + 5;
        const opacity = easeOut(1 - elapsedRatio);

        const style = new Style({
          image: new Circle({
            radius: radius,
            fill: new Fill({
              color: 'rgba(228, 147, 87, ' + opacity + ')'
            }),
            stroke: new Stroke({
              color: 'rgba(255, 0, 0, ' + opacity + ')',
              width: 1 + opacity
            })
          })
        });
        // 将feature渲染到画布中。
        vectorContext.drawFeature(f.clone(), style);
      });
    mapRef.value.map.render();
  }
};
</script>
<style scoped lang="scss">
.toolbar {
  position: absolute;
  top: 20px;
  left: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
相关推荐
Cloud_Shy61815 分钟前
解读《Effective Python 3rd Edition》:从练气到老魔
开发语言·python
雨辰AI21 分钟前
MySQL 迁移至达梦 DM9 完整改造指南|99% SQL 零改动
java·开发语言·数据库·sql·mysql·政务
弹简特24 分钟前
【Java项目-轻聊】05-AI赋能设计接口文档
java·开发语言
AI行业学习27 分钟前
.NET Framework 3.5 SP1 完整离线包(2029.5.29)
开发语言·windows·.net
cany100028 分钟前
C++ -- 队列std::queue
开发语言·c++
MageGojo29 分钟前
做节日活动页时,如何用 API 快速生成对联内容
javascript·python·节日·对联生成
skywalk816333 分钟前
根据言律的语法,能否用racket进行开发呢?主要探讨是否可行。 racket在这里:E:\Program Files\Racket\Racket.exe
开发语言·原型模式
OctShop大型商城源码34 分钟前
OctShop对比JAVA商城源码_OctShop大型专业级多用户商城源码
java·开发语言·商城系统·小程序商城·octshop
l1t35 分钟前
DeepSeek总结的使用实体-组件-系统和基于存在性处理进行Python编程15-17
开发语言·数据库·python
guslegend38 分钟前
AGENT.md,Skill与工程规范
java·开发语言·数据库