前言
在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.效果
总结
需要源代码的请私聊我,有不足的地方也可以指出来共同进步