【问题标题】:Is there a way to render animated transparent gif on canvas and change the delay between frames有没有办法在画布上渲染动画透明 gif 并更改帧之间的延迟
【发布时间】:2019-12-11 12:53:02
【问题描述】:

我正在开发一个网站,可以在其中提供指向透明动画 gif(通常来自 giphy)的链接,并且我想在画布上呈现(动画)它,同时保持动画 gif 的透明度。这样可以改变 GIF 的动画速度。

我已经尝试使用以下方法

  • fastgif 但三十帧中只有一帧显示图像,其余的完全透明。不透明的 Gif 也可以。

  • gifuct-js 但背景为黑色且不透明。我知道 gifuct 提供了一个透明度索引,但它在解码 gif 时没有显示。

我尝试了许多不同的 gif,包括不是来自使用 Photoshop 和 After Effects 创建的 giphy 但没有结果的 gif。


fastgif(其中all 是使用fetch 获取的解码后的gif)

import { Decoder } from 'fastgif'
const d = new Decoder()
window.fetch('https://media.giphy.com/media/tTutsU63rnHC8/giphy.gif')
  .then((response) => response.arrayBuffer())
  .then((buffer) => d.decode(buffer))
  .then(async (frames) => {
  const canvas = document.createElement('canvas');
  canvas.width = all[0].imageData.width;
  canvas.height = all[0].imageData.height;
  const ctx = canvas.getContext('2d');
  let frame = 0;
  while (true) {
    ctx.putImageData(all[frame].imageData, 0, 0);
    await new Promise((resolve) => window.setTimeout(resolve, all[frame].delay));
    if (++frame === all.length) {
      frame = 0;
    }
  }
})

gifuct-js 这个我只尝试渲染一帧看透明度是否有效,但背景全黑,没有任何透明度。

var tempCanvas = document.createElement('canvas')
var tempContext = tempCanvas.getContext('2d')

window.fetch('https://media.giphy.com/media/tTutsU63rnHC8/giphy.gif')
  .then((response) => response.arrayBuffer())
  .then((buffer) => new GIF(buffer))
  .then((gif) => gif.decompressFrames(true))
  .then(async (frames) => {
    const frame = frames[0]
    const dims = frame.dims
    c.width = dims.width
    c.height = dims.height
    tempCanvas.width = dims.width
    tempCanvas.height = dims.height
    const imageData = tempContext.createImageData(dims.width, dims.height)
    tempContext.putImageData(imageData, 0, 0)
    // set the patch data as an override
    imageData.data.set(frame.patch)
    let pix = imageData.data
    ctx.clearRect(0, 0, c.width, c.height)
    ctx.drawImage(tempCanvas, 0, 0)
    ctx.putImageData(imageData, 0, 0)
    image.src = tempCanvas.toDataURL('image/png')
  })

如果将<img src='https://media.giphy.com/media/tTutsU63rnHC8/giphy.gif' /> 添加到网站,我希望渲染看起来像。带有透明背景的动画。

【问题讨论】:

    标签: javascript html canvas gif transparent


    【解决方案1】:

    这是我发现的一个涉及 gifler 和 konvajs 的解决方案: https://konvajs.org/docs/sandbox/GIF_On_Canvas.html.

    更新这是一个需要调整延迟的解决方案(注意onDrawFrame 函数中的注释。

    var width = window.innerWidth;
    var height = window.innerHeight;
    
    var stage = new Konva.Stage({
      container: 'container',
      width: width,
      height: height,
    });
    
    var layer = new Konva.Layer();
    stage.add(layer);
    
    var canvas = document.createElement('canvas');
    // use external library to parse and draw gif animation
    function onDrawFrame(ctx, frame) {
      /*
        Here is where you can adust the delay between frames.
      */
      frame.delay = 80;
      // update canvas that we are using for Konva.Image
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.drawImage(frame.buffer, frame.x, frame.y);
      // redraw the layer
      layer.draw();
    }
    
    gifler('https://media1.giphy.com/media/l4pTpdRiFv10jFlNC/200w_d.gif').frames(canvas, onDrawFrame, true);
    // draw resulted canvas into the stage as Konva.Image
    var image = new Konva.Image({
      image: canvas
    });
    layer.add(image);
    <!DOCTYPE html>
    <html>
    
    <head>
      <script src="https://unpkg.com/konva@3.4.1/konva.min.js"></script>
      <script src="https://unpkg.com/gifler@0.1.0/gifler.min.js"></script>
      <meta charset="utf-8" />
      <style>
        body {
          margin: 0;
          padding: 0;
          overflow: hidden;
          background-color: #f0f0f0;
        }
      </style>
    </head>
    
    <body>
      <div id="container"></div>
    </body>
    
    </html>

    【讨论】:

    • 这非常适合渲染透明的 GIF,谢谢。但是我找不到改变gifler每帧之间延迟的方法。有任何想法吗?我尝试使用get() 来获取完整的动画师,但缺少文档让我无处可去。
    • @Victor 我做了一些调整来展示如何添加延迟。
    猜你喜欢
    • 1970-01-01
    • 2012-02-08
    • 2016-03-11
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 2013-02-15
    • 2014-04-15
    相关资源
    最近更新 更多