使用 gif-encoder 和 dom-to-image 库将 DOM 节点导出到 GIF
export DOM Node to GIF with gif-encoder and dom-to-image libs
我正拼命尝试从客户端的 DOM 节点导出非动画 gif,但还没有成功。
我为此使用了库 dom-to-image,多亏了它的方法 toPixelData
,return 一些像素。
然后我希望这些像素给我一个 gif。我为此使用了 lib gif-encoder,这听起来不错。
我考虑为此使用 Promise,因为最后一步是将此 gif 放入由 JSZip.
创建的 ZIP 文件中
这是下面的代码。假设我已经将 DOM 节点作为输入,并预定义了 height
和 width
。一切进展顺利,直到我需要将我的 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
对于事件 data
和 false
对于事件 end
,结果是相同的:大小为 0 的 Blob。
哪里错了?
所以 gif-encoder
lib found the solution 的创建者,它在下面。如果我可以引用他的话:
Our library outputs the GIF as data, not as an DOM element or similar. To aggregate this content, you can collect the stream into a buffer or pass it along to its target
所以正确的代码最终是:
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));
我正拼命尝试从客户端的 DOM 节点导出非动画 gif,但还没有成功。
我为此使用了库 dom-to-image,多亏了它的方法 toPixelData
,return 一些像素。
然后我希望这些像素给我一个 gif。我为此使用了 lib gif-encoder,这听起来不错。
我考虑为此使用 Promise,因为最后一步是将此 gif 放入由 JSZip.
这是下面的代码。假设我已经将 DOM 节点作为输入,并预定义了 height
和 width
。一切进展顺利,直到我需要将我的 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
对于事件 data
和 false
对于事件 end
,结果是相同的:大小为 0 的 Blob。
哪里错了?
所以 gif-encoder
lib found the solution 的创建者,它在下面。如果我可以引用他的话:
Our library outputs the GIF as data, not as an DOM element or similar. To aggregate this content, you can collect the stream into a buffer or pass it along to its target
所以正确的代码最终是:
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));