• 设置时间函数 setInterval() 、通过canvas截取video元素固定时间间隔的帧画面
  • 调用 gif.addFrame() ,将截取画面作为 gif 中的一帧追加到gif图中
  • 监听视频播放完毕的 onended 事件,调用 gif.render() 完成对gif添加帧的渲染
  • 监听 gif.on('finished', function(blob){}) 将blob转为可下载链接并下载到本地
  • var
    
    
    
    
        
     gif = new GIF({
      quality: 10, // gif 清晰度,越低越清晰
      workerScript: './gif.worker.js', // 借助worker运行video解决视频跨域问题
      debug: true // 开启调试模式
    // 将canvas节点追加到gif帧中,delay 是每一帧的时间间隔
    gif.addFrame(canvasElement, {delay: 200});
    // 监听渲染完成,返回 blob 文件流
    gif.on('finished', function(blob) {
      const url = URL.createObjectURL(blob);
    // 将每一帧渲染成一张完成的gif
    gif.render();
    
    // 本地上传视频文件,生成视频url
    input.addEventListener('change', () => {
        const videoFile = e.target.files[0];
        const videoUrl = URL.createObjectURL(videoFile)
        video.setAttribute('src', videoUrl);  
    
    // 创建GIF
    const videoGif = new GIF({
        workers: 2,
        quality: 1,
        workerScript: './gif.worker.js',
        debug: true
    // 设定时间间隔
    const delay = 100; 
    
    // video 事件监听与播放
    video.addEventListener('loadedmetadata', () => {
        // 部分视频尺寸可能会很大,可以再加载完成时设置样式缩小其尺寸
        const width = this.video.videoWidth / 5;
        const height = this.video.videoHeight / 5;
        video.setAttribute('style', `width:${width}px;height:${height}px`);
    video.addEventListener('ended' = () => {
        // 视频播放完毕,清除时间函数
        clearInterval(timer);
        // 将追加的gif帧,渲染成完整图
        videoGif.render()
        // 监听渲染完毕,并输出 gif 地址
        videoGif.on('finished', blob => {
            const gifImg = URL.createObjectURL(blob);
    video.play(); // 播放视频
    
    // 创建canvas
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext('2d');
    // 设置时间函数
    const timer = setInterval(() => {
        // 画布的宽高与视频宽高保持一致,延迟取上面定义的延迟时间
        canvas.width = width;
        canvas.height = height;
        canvas.delay = delay
        canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); 
        // 将当前画面帧追加到 gif中
        const imgImage = new Image();
        imgImage.src = canvas.toDataURL("image/png");
        imgImage.onload = (e) => {
          // 绘制底色  
          ctx.fillRect(0, 0, canvas.width, canvas.height);
          // 绘制当前帧
          ctx.drawImage(imgImage, 0, 0, canvas.width, canvas.height);
          // 当前帧追加到gif中
          gif.addFrame(canvas, {copy: true, delay: canvas.delay});
    }, delay)
    
    // 下载转换后的gif图
    download.addEventListener('click', () => {
        const aLink = document.createElement('a');
        aLink.setAttribute('download', 'img')
        aLink.setAttribute('href', gifImg)
        aLink.click()
    

    DEMO 在线体验

    Canvas VIP.4 融会贯通
    私信