Cesium中加载GIF动画

前言

在cesium项目中,Cesium 使用 canvas 渲染,如果通过传统的 billboard 等方法加载 gif 图片,往往只能渲染出第一帧,导致动画无法播放,为了解决这个问题,可以采取以下几种方法:

1.使用第三方库解析GIF:使用如 libgif 或 SuperGif 等第三方库将 GIF 解析成多帧图片,然后通过 Cesium 的 BillboardGraphics 方法,按照时间顺序更新 billboard 的图片,从而实现动画效果。

2.将HTML元素渲染到地图上:在 Cesium 的官方示例中,有一种方法是将 HTML 元素(比如一个 img 标签)渲染到地图上。通过这种方式,GIF 图可以完整加载并且动画能够正常播放。这种方法可以使用 CSS 调节页面元素的样式。(自定义html)

接下来我们主要讲的是第一种方式实现加载gif动画

一、原理

1.canvas、img、video,都是图像对象,属于图像类型的节点。这种图像对象不是Image 对象,而是对加载图像数据流的节点的统称。

img 里的图像数据来源于提前制作好图片文件的,是静止的,比如.jpg,.png,.svg 等。.gif 是个特殊存在,另当别论。
vedio 里的视频数据来源于提前制作好的视频文件,是动起来的。
canvas 图像数据是动态生成的。
2.图像对象的数据的读写

读取图像数据

img 和video 没有直接获取ImageData 的方法,但可以通过canvas 获取
canvas 使用getImageData 方法读取自身的图像数据
写入图像数据

img 和video 只能通过src ,以资源路径的方式设置其显示图像(img 的src 还可以使用base64)。但他们无法直接用ImageData 设置图像。
canvas 可以用drawImage 或fillStyle 方法,以图像对象为参数,为canvas 或其内部元素写入图像数据。canvas 也可以通过putImageData方法,以ImageData 对象为参数,为其写入图像数据。
gif 是介于图片和视频之间的特殊存在。
用读取image 数据的原理读取它,只能读到第一帧gif 图片。

直接绘制gif 肯定是不好使的,这里就用到了一个插件libgif.js

二、插件libgif.js

1.地址

libgif.js网址:github.com/buzzfeed/libgif-js

2.使用

cesium 加载gif广告牌

import SuperGif from "./libgif.js";
export default class GifMarker {
  constructor(viewer, option) {
    this.viewer = viewer
    this.position = option.position
    this.url = option.url
    this.createGif()
  }
  async createGif() {
    let div = document.createElement("div");
    let img = document.createElement("img");
    div.appendChild(img);
    img.src = require('./img/'+this.url);
    await new Promise((resolve, reject) => {
      img.onload = () => {
        let rub = new SuperGif({
          gif: img
        })
        rub.load(() => {
          const entity = this.viewer.entities.add({
            position: this.position,
            billboard: {
              image: new Cesium.CallbackProperty(() => {
                return rub.get_canvas().toDataURL("image/png");
              }, false),
              scale: 0.3,
              scaleByDistance: new Cesium.NearFarScalar(10, 1.2, 50, 1.2),
              distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 600000),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
              disableDepthTestDistance: 1000000
            },
          });
          resolve(entity);
        });
      };
      img.onerror = (error) => {
        reject(error);
      };
    });
  }
}

2.效果在这里插入图片描述


总结

需要源代码的请私聊我,有不足的地方也可以指出来共同进步

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

简单灬爱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值