使用gif编码器和dom-to-image库将DOM节点导出到GIF

时间:2018-10-18 15:07:25

标签: javascript stream blob gif fs

我正拼命尝试从客户端的DOM节点获取非动画gif导出,但仍未成功。

我为此使用了库dom-to-image,由于它的方法toPixelData,它返回了一些像素。 然后我要这些像素给我一个gif。为此,我使用了lib gif-encoder,听起来不错。 我考虑过为此使用Promise,因为最后一步是将gif放在JSZip创建的ZIP文件中。

这是下面的代码。考虑到我已经将DOM节点作为输入,并带有预定义的heightwidth。一切进展顺利,直到需要将我的GifEncoder实例转换为Blob才能下载它的步骤为止。

import domtoimage from 'dom-to-image';
import GifEncoder from 'gif-encoder';
const fs = require('localstorage-fs');
const toBlob = require('stream-to-blob');
import JSZip from 'jszip';

const pixelsToGIF = (pixels, width, height) =>
  new Promise((resolve, reject) => {
    const gif = new GifEncoder(width, height);
    const gifFile = fs.createWriteStream('image.gif');
    gif.pipe(gifFile);
    gif.writeHeader();
    gif.addFrame(pixels);
    gif.finish();
    gif.on('data', function() {
      console.log(this); //GIFEncoder, a constructor function which extends readable-stream@~1.1.9 (cf doc.)
      toBlob(this, function (err, blob) {
        console.error(err) // No error
        console.log(blob) // Blob of size 0
        resolve(blob)
      })
    })
    gif.on('error', reject)
  })

const zip = new JSZip();
domtoimage
.toPixelData(DOMNode, { width, height })
.then(pixels => pixelsToGIF(pixels, 'image.gif', width, height))
.then(gif => { 
  console.log(gif); // Blob of size 0
  zip.file('image.gif', gif)
})
.catch(e => console.log('couldn\'t export to GIF', e));

我还尝试使用gif.on('end', function () {} )来代替gif.on('data'),但除了属性readable(用于事件true的{​​{1}})之外,和事件data的{​​{1}},结果相同:大小为0的Blob。 错误在哪里?

1 个答案:

答案 0 :(得分:0)

因此gif-encoder lib found the solution的创建者在下面。如果我可以引用他的话:

  

我们的库将GIF输出为数据,而不是DOM元素或类似元素。要聚合此内容,您可以将流收集到缓冲区中或传递到其目标

因此,正确的代码终于是:

import domtoimage from 'dom-to-image';
import concat from 'concat-stream';
import GifEncoder from 'gif-encoder';
import JSZip from 'jszip';

const pixelsToGIF = (pixels, width, height) =>
  new Promise((resolve, reject) => {
    const gif = new GifEncoder(width, height);
    gif.pipe(concat(resolve));
    gif.writeHeader();
    gif.addFrame(pixels);
    gif.finish();
    gif.on('error', reject);
  })

const zip = new JSZip();
domtoimage
.toPixelData(DOMNode, { width, height })
.then(pixels => pixelsToGIF(pixels, 'image.gif', width, height))
.then(gif => zip.file('image.gif', gif))
.catch(e => console.log('couldn\'t export to GIF', e));