экспортировать DOM-узел в GIF с помощью gif-кодировщика и библиотек dom-to-image - PullRequest
0 голосов
/ 18 октября 2018

Я отчаянно пытаюсь получить экспорт без анимации из DOM-узла на стороне клиента, но пока безуспешно.

Я использую для этого lib dom-to-image , который, благодаря его методу toPixelData, возвращает несколько пикселей.Тогда я хочу, чтобы эти пиксели дали мне подарок.Я использую для этого lib gif-encoder , который звучит великолепно.Я подумал об использовании Promise для этого, потому что последний шаг - поместить этот gif в ZIP-файл, созданный JSZip .

Вот код ниже.Учтите, что у меня уже есть узел DOM в качестве входа, с предопределенными height и width.Все идет довольно хорошо, до того момента, когда мне нужно преобразовать мой экземпляр GifEncoder в большой двоичный объект, чтобы загрузить его.

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, результат тот же: BLOB-объект размера 0. Гдеэто ошибка?

1 Ответ

0 голосов
/ 19 октября 2018

Итак, создатель gif-encoder lib нашел решение , и вот оно ниже.Если я могу процитировать его:

Наша библиотека выводит 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));
...