cesium 加载gif解决

本文分享了如何在Cesium中加载和显示GIF图片的实践经验,通过引入libgif.js库,实现动态GIF在三维场景中的流畅播放。
摘要由CSDN通过智能技术生成

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
  <title>Hello World!</title>
  <link href="../Cesium/Widgets/widgets.css" rel="stylesheet" />
  <script src="../Cesium/Cesium.js"></script>
  <script src="libgif.js"></script>
</head>
<body>
<div id="cesiumContainer" class="fullSize"></div>
<script>
  Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJlZWVhNjZkZS0yZDgzLTRhZGEtOGJkYS1iMWUxNmM3NzNmNmUiLCJpZCI6NjM1MzEsImlhdCI6MTYyODIyNzYyMn0.Swb3G8ZboOXzXXiMLjEXIErFjXXZmbZrFIKXCxtIxnQ';
  var viewer = new Cesium.Viewer("cesiumContainer");
  testGif()
  function testGif() {
   
    const gifDiv = document.createElement('div');
    const gifImg = document.createElement('img');

    // gif库需要img标签配置下面两个属性
    gifImg.setAttribute('rel:animated_src', '10000.gif')
    gifImg.setAttribute('rel:auto_play', '0')
    gifDiv.appendChild(gifImg);

    // 新建gif实例
    var rub = new SuperGif({
    gif: gifImg } );

    rub.load(function () {
   
      var img_list = [];

      // 获取 gif 图的每一帧图片(通过修改i的值  来控制gif 的频率)
      for (var i=1; i <= rub.get_length(); i++) {
   
        // 遍历gif实例的每一帧
        rub.move_to(i);
        img_list.push(rub.get_canvas().toDataURL())
      }

      let flag = 0;
      let len = img_list.length;
      // 创建图片实体
      let gif_entity = viewer.entities.add({
   
        position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883,500),
        //参数具体查看api
        billboard: {
   
          width: 100,
          height: 56,
          image: img_list[0],
          scale: 1,
          pixelOffset: new Cesium.Cartesian2(0, 0),
          eyeOffset: new Cesium.Cartesian3(0, 0.0, 0.0),
          horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
          alignedAxis: Cesium.Cartesian3.CENTER,
          scaleByDistance: new Cesium.NearFarScalar(20, 2, 150, 0.3),
          depthTestAgainstTerrain: false
        }
      });

      // 循环更新 billboard
      setInterval(() => {
   
        flag++;
        if (flag >= len) {
   
          flag = 0;
        }
        gif_entity.billboard.image = img_list[flag];
      }, 1000 / 30);
    });
  }
</script>


</body>
</html>

libgif.js

/*
	SuperGif

	Example usage:

		<img src="./example1_preview.gif" rel:animated_src="./example1.gif" width="360" height="360" rel:auto_play="1" />

		<script type="text/javascript">
			$$('img').each(function (img_tag) {
				if (/.*\.gif/.test(img_tag.src)) {
					var rub = new SuperGif({ gif: img_tag } );
					rub.load();
				}
			});
		</script>

	Image tag attributes:

		rel:animated_src -	If this url is specified, it's loaded into the player instead of src.
							This allows a preview frame to be shown until animated gif data is streamed into the canvas

		rel:auto_play -		Defaults to 1 if not specified. If set to zero, a call to the play() method is needed

	Constructor options args

		gif 				Required. The DOM element of an img tag.
		loop_mode			Optional. Setting this to false will force disable looping of the gif.
		auto_play 			Optional. Same as the rel:auto_play attribute above, this arg overrides the img tag info.
		max_width			Optional. Scale images over max_width down to max_width. Helpful with mobile.
 		on_end				Optional. Add a callback for when the gif reaches the end of a single loop (one iteration). The first argument passed will be the gif HTMLElement.
		loop_delay			Optional. The amount of time to pause (in ms) after each single loop (iteration).
		draw_while_loading	Optional. Determines whether the gif will be drawn to the canvas whilst it is loaded.
		show_progress_bar	Optional. Only applies when draw_while_loading is set to true.

	Instance methods

		// loading
		load( callback )		Loads the gif specified by the src or rel:animated_src sttributie of the img tag into a canvas element and then calls callback if one is passed
		load_url( src, callback )	Loads the gif file specified in the src argument into a canvas element and then calls callback if one is passed

		// play controls
		play -				Start playing the gif
		pause -				Stop playing the gif
		move_to(i) -		Move to frame i of the gif
		move_relative(i) -	Move i frames ahead (or behind if i < 0)

		// getters
		get_canvas			The canvas element that the gif is playing in. Handy for assigning event handlers to.
		get_playing			Whether or not the gif is currently playing
		get_loading			Whether or not the gif has finished loading/parsing
		get_auto_play		Whether or not the gif is set to play automatically
		get_length			The number of frames in the gif
		get_current_frame	The index of the currently displayed frame of the gif

		For additional customization (viewport inside iframe) these params may be passed:
		c_w, c_h - width and height of canvas
		vp_t, vp_l, vp_ w, vp_h - top, left, width and height of the viewport

		A bonus: few articles to understand what is going on
			http://enthusiasms.org/post/16976438906
			http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp
			http://humpy77.deviantart.com/journal/Frame-Delay-Times-for-Animated-GIFs-214150546

*/
(function (root, factory) {
   
    if (typeof define === 'function' && define.amd) {
   
        define([], factory);
    } else if (typeof exports === 'object') {
   
        module.exports = factory();
    } else {
   
        root.SuperGif = factory();
    }
}(this, function () {
   
    // Generic functions
    var bitsToNum = function (ba) {
   
        return ba.reduce(function (s, n) {
   
            return s * 2 + n;
        }, 0);
    };

    var byteToBitArr = function (bite) {
   
        var a = [];
        for (var i = 7; i >= 0; i--) {
   
            a.push( !! (bite & (1 << i)));
        }
        return a;
    };

    // Stream
    /**
     * @constructor
     */
    // Make compiler happy.
    var Stream = function (data) {
   
        this.data = data;
        this.len = this.data.length;
        this.pos = 0;

        this.readByte = function () {
   
            if (this.pos >= this.data.length) {
   
                throw new Error('Attempted to read past end of stream.');
            }
            if (data instanceof Uint8Array)
                return data[this.pos++];
            else
                return data.charCodeAt(this.pos++) & 0xFF;
        };

        this.readBytes = function (n) {
   
            var bytes = [];
            for (var i = 0; i < n; i++) {
   
                bytes.push(this.readByte());
            }
            return bytes;
        };

        this.read = function (n) {
   
            var s = '';
            for (var i = 0; i < n; i++) {
   
                s += String.fromCharCode(this.readByte());
            }
            return s;
        };

        this.readUnsigned = function () {
    // Little-endian.
            var a = this.readBytes(2);
            return (a[1] << 8) + a[0];
        };
    };

    var lzwDecode = function (minCodeSize, data) {
   
        // TODO: Now that the GIF parser is a bit different, maybe this should get an array of bytes instead of a String?
        var pos = 0; // Maybe this streaming thing should be merged with the Stream?
        var readCode = function (size) {
   
            var code = 0;
            for (var i = 0; i < size; i++) {
   
                if (data.charCodeAt(pos >> 3) & (1 << (pos & 7))) {
   
                    code |= 1 << i;
                }
                pos++;
            }
            return code;
        };

        var output = [];

        var clearCode = 1 << minCodeSize;
        var eoiCode = clearCode + 1;

        var codeSize = minCodeSize + 1;

        var dict = [];

        var clear = function () {
   
            dict = [];
            codeSize = minCodeSize + 1;
            for (var i = 0; i < clearCode; i++) {
   
                dict[i] = [i];
            }
            dict[clearCode] = [];
            dict[eoiCode] = null;

        };

        var code;
        var last;

        while (true) {
   
            last = code;
            code = readCode(codeSize);

            if (code === clearCode) {
   
                clear();
                continue;
            }
            if (code === eoiCode) break;

            if (code < dict.length) {
   
                if (last !== clearCode) {
   
                    dict.push(dict[last].concat(dict[code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值