JavaScript基于libgif.js实现控制gif动画帧

 更新时间:2024年02月03日 15:35:20   作者:夏末_阳光依然耀眼  
这篇文章主要为大家详细介绍了JavaScript如何利用libgif.js插件控制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

libgif.js已经完成了对gif 的解析,并将其写入了canvas 中。

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

下面是我从官网上复制粘贴下来,用百度翻译一下 ,然后略作调整。英语好的可以跳过这里,看官网。

1.写在图片标签里的属性 Image tag attributes

  • rel:animated_src - 如果指定了此url,则将其加载到播放器而不是src中。这允许显示预览帧,直到动画gif数据流入画布
  • rel:auto_play - 如果未指定,则默认为1。如果设置为零,则需要调用play()方法
  • rel:rubbable - 如果未指定,则默认为0。如果设置为1,则gif将是一个带有处理程序的画布来处理摩擦。

2.构造函数 Constructor options

  • gif - 必填。img标签的DOM元素。
  • loop_mode - 可选。将此设置为false将强制禁用gif的循环。
  • auto_play - 可选。与上面的rel:auto_play属性相同,此arg会覆盖img标记信息。
  • max_width - 可选。将图像从max_width缩放到max_width。有助于移动。
  • rubbable - 可选。让它可以擦掉。
  • on_end - 可选。添加一个回调,用于当gif到达单个循环结束时(一次迭代)。传递的第一个参数将是gif HTMLElement。
  • loop_delay - 可选。每次循环(迭代)后暂停的时间(以毫秒为单位)。
  • progressbar_height - 可选。进度条的高度。
  • progressbar_background_color - 可选。进度条的背景颜色。
  • progressbar_foreground_color - 可选。进度条的前景色。

3.loading 事件

  • load(callback) - 将src指定的gif或img标记的rel:animated_src sttributie加载到canvas元素中,然后调用callback(如果有的话)
  • load_url(src,callback) - 将src参数中指定的gif文件加载到canvas元素中,如果传递了一个,则调用callback

4.播放控制器 play controls

  • play - 开始玩GIF
  • pause - 停止播放gif
  • move_to(i) - 移动到gif的第i帧
  • move_relative(i) - 向前移动i帧(如果i <0则向后移动)

5.数据获取 getters

  • get_canvas - gif正在播放的canvas元素。方便分配事件处理程序。
  • get_playing - gif当前是否正在播放
  • get_loading - gif是否已完成加载/解析
  • get_auto_play - 是否将gif设置为自动播放
  • get_length - gif中的帧数
  • get_current_frame - 当前显示的gif帧的索引

6.官方案例

<center>
	<h1>控制gif播放/暂停/快进快退</h1>
	<img id="example1" src="./example_gifs/rub_test_preview.jpg" rel:animated_src="./example_gifs/rub_test.gif" rel:auto_play="0" width="467" height="375" />
	<br>
	<script type="text/javascript">
		var sup1 = new SuperGif({ gif: document.getElementById('example1') } );
		sup1.load();
	</script>
	<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  onmousedown="sup1.play(); return false;">播放</a> |
	<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  onmousedown="sup1.pause(); return false;">暂停</a>
	<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  onmousedown="sup1.move_to(0); return false;">还原</a> |
	<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  onmousedown="sup1.move_relative(1); return false;">下一帧</a> |
	<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  onmousedown="sup1.move_relative(-1); return false;">上一帧</a>
</center>                
                
<img src="./example1_preview.gif" rel:animated_src="./example1.gif"
width="360" height="360" rel:auto_play="1" rel:rubbable="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(function(){
                                console.log('oh hey, now the gif is loaded');
                        });
                }
        });
</script>

提示:

  • RubbableGif 对象继承自 SuperGif 对象,SuperGif是解析gif 的核心。
  • 前端建立的 节点,只是一个向SuperGif 对象传递数据的工具,等SuperGif 解析完了gif,就会用canvas 将img 替换掉。

三、实际应用

前景是这样的,用gif做一个进度条,等待gif动画播放完成后,显示按钮;

一开始我是用了一个定时器设置时间跟gif动画时间一样长,时间到动画播放完成,按钮显示,没毛病; 但是,在实际运用过程中发现,加载gif由于网络原因跟定时器就不会同步,很多情况是,定时器走完了,gif才播放一半,显然效果不理想,后来经过产品提醒,能不能判断gif播放完毕后,再显示这个按钮;于是查找资料,发现了这个libgif.js插件挺好的,于是做了尝试,完美解决问题,在此记录一下。

本文重点讲述运用libgif.js实现,加载一个load.gif完成后,进行下一步的业务逻辑,代码如下:

<!--样式-->
<style type="text/css">
*{margin: 0; padding: 0;}
.load_p{ position: relative; width: 100vw; height: 100vh; }
a.play_2{display: none; position: absolute; left: 50%; top: 50%; margin-left:-370px; margin-top:-37px;}
</style>
<!--dom结构-->
<script type="text/javascript" src="./libgif.js"></script>
<div class="load_p">
	<img id="load" src="./example_gifs/loadbg.gif" rel:animated_src="./example_gifs/loadbg.gif" rel:auto_play="0"/>	
	<a href="javascript://" rel="external nofollow"  class="play_2" id="btn"><img src="./example_gifs/p1_btn_v.png" alt=""/></a>  
</div>
<!--js-->
<script type="text/javascript">
var gif = new SuperGif({ 
	gif: document.getElementById('load'), //img标签的DOM元素。
	loop_mode:false, //将此设置为false将强制禁用gif的循环。
	progressbar_foreground_color: "rgba(255,255,255,0.1)",
    progressbar_background_color: "rgba(255,255,255,0.1)",
    progressbar_height: 1
});
gif.load(function() {
    var lastFrameIndex = gif.get_length() - 1; // 获取最后一帧的索引
    gif.play(); 

    // 设置一个定时器,周期性检查当前帧
    var timer = setInterval(function() {
        if (gif.get_current_frame() === lastFrameIndex) {
            console.log("播放结束");
            document.getElementById('btn').style.display='block';
            clearInterval(timer); // 清除定时器            
        }
    }, 100); 
});
</script>

最终效果,是loadbg.gif动画播放完成后,a.play_2按钮显示。

附上libgif.js github:github.com/buzzfeed/libgif-js?tab=readme-ov-file

到此这篇关于JavaScript基于libgif.js实现控制gif动画帧的文章就介绍到这了,更多相关JavaScript控制动画帧内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS中prototype的用法实例分析

    JS中prototype的用法实例分析

    这篇文章主要介绍了JS中prototype的用法,实例分析了JS中prototype的常见使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • 微信小程序实现天气预报功能

    微信小程序实现天气预报功能

    这篇文章主要为大家详细介绍了微信小程序实现天气预报功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • asp批量修改记录的代码

    asp批量修改记录的代码

    asp 数组 批量修改记录的实现代码
    2008-06-06
  • JavaScript中的JSON转为Python可读取

    JavaScript中的JSON转为Python可读取

    本文主要介绍了JavaScript中的JSON转为Python可读取,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • 详解如何准确判断JavaScript中的数据类型

    详解如何准确判断JavaScript中的数据类型

    JavaScript中,我们经常需要判断数据类型以便于正确地处理数据,本文将介绍JavaScript中的数据类型判断技术,包括typeof操作符、instanceof操作符、Object.prototype.toString方法以及ES6新增的一些数据类型判断方法,需要的朋友可以参考下
    2023-08-08
  • js获取新浪天气接口的实现代码

    js获取新浪天气接口的实现代码

    下面小编就为大家带来一篇js获取新浪天气接口的实现代码。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • 前端判断节假日的详细代码举例

    前端判断节假日的详细代码举例

    因为要做一个日历控件,遇到国家法定节假日,怎么实现此功能呢?这篇文章主要给大家介绍了关于前端判断节假日的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-08-08
  • 利用chrome浏览器进行js调试并找出元素绑定的点击事件详解

    利用chrome浏览器进行js调试并找出元素绑定的点击事件详解

    “工欲善其事,必先利其器” 恩,这句话我觉得说的特别有道理,下面这篇文章主要给大家介绍了关于利用chrome浏览器进行js调试并找出元素绑定的点击事件的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-09-09
  • js使用eval解析json(js中使用json)

    js使用eval解析json(js中使用json)

    eval的用法eval函数接收一个参数s,如果s不是字符串,则直接返回s。否则执行s语句,下面给出eval解析json的示例
    2014-01-01
  • JS中取二维数组中最大值的方法汇总

    JS中取二维数组中最大值的方法汇总

    本文通过三种解决方案给大家介绍js中取二维数组中最大值的方法。介绍的非常详细,具有参考价值
    2016-04-04

最新评论