四、openlayers官网示例Animated GIF解析——地图上加载GIF动画

这篇讲的是如何在地图上加载gif动画,因为openlayers本身是不支持插入gif动画的,因此我们要下一个gifler插件。

npm i gifler

npm下下来之后发现直接import和require引入都不行,好嘛,直接引入算了

在node_moudles里面找到这个文件,复制出来

直接丢到项目public/gifler下面

在index.html下面引入gifler

<script src="gifler/gifler.min.js"></script>

 

顺便在网上找一张gif动画放到data目录下。

然初始化一个map,这次用到的是StadiaMaps底图,我试了下应该是可以直接加载出来的。

 const rasterLayer = new TileLayer({
      source: new StadiaMaps({
        layer: "stamen_toner",
      }),
    });

    const map = new Map({
      layers: [rasterLayer],
      target: document.getElementById("map"),
      view: new View({
        center: [116.389, 39.903],
        zoom: 8,
        projection: "EPSG:4326",
      }),
    });

然后是加一个矢量点上去

 const iconFeature = new Feature({
      geometry: new Point([116.389, 39.903]),
    });

    const vectorSource = new VectorSource({
      features: [iconFeature],
    });

    const vectorLayer = new VectorLayer({
      source: vectorSource,
    });

feature放到source上,source放到layer上 layer放到地图上 

feature ->source->layer->map

然后把我们下载的gif加载到地图上,注意gif文件的地址不要写错了。

gifler(gifUrl).frames是gitler的一个方法,在里面打印会发现控制台会一直输出,看了下它的源码,大胆猜测一下,我感觉它是把gif的每一帧返回过来,然后通过canvas绘制图片的方法ctx.drawImage绘制到地图上,再调了map.render()实时渲染地图。不知道对不对,感兴趣的可以看下源码

gifler - npm

const gifUrl = "data/dog.gif";
    const gif = gifler(gifUrl);
    gif.frames(
      document.createElement("canvas"),
      function (ctx, frame) {
        if (!iconFeature.getStyle()) {
          iconFeature.setStyle(
            new Style({
              image: new Icon({
                img: ctx.canvas,
                opacity: 1,
              }),
            })
          );
        }
        ctx.clearRect(0, 0, frame.width, frame.height);
        ctx.drawImage(frame.buffer, frame.x, frame.y);
        // 渲染地图
        map.render();
      },
      true
    );

然后再是鼠标移动事件,getFeaturesAtPixel 方法会返回一个当前鼠标移动的坐标数组,hasFeatureAtPixel检查指定像素位置下是否存在地图要素(features)返回一个布尔值,然后动态改变鼠标的css样式。

map.on("pointermove", function (e) {
      const pixel = map.getEventPixel(e.originalEvent);
      const hit = map.hasFeatureAtPixel(pixel);
      map.getTarget().style.cursor = hit ? "pointer" : "";
    });

个人感觉这种方式加载gif不是很好,比如我要同时加载多个点位的gif动画,每张gif图片的大小还不一样,就有些难办。改鼠标样式也很麻烦。如果项目中有需求要加载多个gif建议使用Overlay,不要用这种矢量点的方式。

完整代码:

<template>
  <div class="box">
    <h1>Animated GIF</h1>
    <div id="map"></div>
  </div>
</template>

<script>
import Feature from "ol/Feature.js";
import Map from "ol/Map.js";
import Point from "ol/geom/Point.js";
import View from "ol/View.js";
import { Icon, Style } from "ol/style.js";
import { StadiaMaps, Vector as VectorSource, ImageCanvas } from "ol/source.js";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";

export default {
  name: "",
  components: {},
  data() {
    return {
      map: null,
    };
  },
  computed: {},
  created() {},
  methods: {},
  mounted() {
    const iconFeature = new Feature({
      geometry: new Point([116.389, 39.903]),
    });

    const vectorSource = new VectorSource({
      features: [iconFeature],
    });

    const vectorLayer = new VectorLayer({
      source: vectorSource,
    });

    const rasterLayer = new TileLayer({
      source: new StadiaMaps({
        layer: "stamen_toner",
      }),
    });

    const map = new Map({
      layers: [rasterLayer, vectorLayer],
      target: document.getElementById("map"),
      view: new View({
        center: [116.389, 39.903],
        zoom: 8,
        projection: "EPSG:4326",
      }),
    });

      const gifUrl = "data/dog.gif";
      const gif = gifler(gifUrl);
      gif.frames(
        document.createElement("canvas"),
        function (ctx, frame) {
          if (!iconFeature.getStyle()) {
            iconFeature.setStyle(
              new Style({
                image: new Icon({
                  img: ctx.canvas,
                  opacity: 1,
                }),
              })
            );
          }
          ctx.clearRect(0, 0, frame.width, frame.height);
          ctx.drawImage(frame.buffer, frame.x, frame.y);
          // 渲染地图
          map.render();
        },
        true
      );
    map.on("pointermove", function (e) {
      const pixel = map.getEventPixel(e.originalEvent);
      const hit = map.hasFeatureAtPixel(pixel);
      map.getTarget().style.cursor = hit ? "pointer" : "";
    });
  },
};
</script>

<style lang="scss" scoped>
#map {
  width: 100%;
  height: 500px;
}
.box {
  height: 100%;
}
</style>

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值