如何将canvas动画保存为gif或webm?

问题描述 投票:0回答:2

我编写了这个函数来捕获

GIF
的每一帧,但输出非常滞后,并且当数据增加时会崩溃。有什么建议吗?

function createGifFromPng(list, framerate, fileName, gifScale) {
    gifshot.createGIF({
        'images': list,
        'gifWidth': wWidth * gifScale,
        'gifHeight': wHeight * gifScale,
        'interval': 1 / framerate,
    }, function(obj) {
        if (!obj.error) {
            var image = obj.image;
            var a = document.createElement('a');
            document.body.append(a);
            a.download = fileName;
            a.href = image;
            a.click();
            a.remove();
        }
    });
}

function getGifFromCanvas(renderer, sprite, fileName, gifScale, framesCount, framerate) {
    var listImgs = [];
    var saving = false;
    var interval = setInterval(function() {
        renderer.extract.canvas(sprite).toBlob(function(b) {
            if (listImgs.length >= framesCount) {
                clearInterval(interval);
                if (!saving) {
                createGifFromPng(listImgs, framerate, fileName,gifScale);
                    saving = true;
                }
            }
            else {
                listImgs.push(URL.createObjectURL(b));
            }
        }, 'image/gif');
    }, 1000 / framerate);
}
javascript html canvas three.js gif
2个回答
71
投票

在现代浏览器中,您可以结合使用 MediaRecorder APIHTMLCanvasElement.captureStream 方法。

MediaRecorder API 将能够动态编码视频或音频媒体文件中的 MediaStream,从而比抓取静态图像时所需的内存少得多。

const ctx = canvas.getContext('2d');
var x = 0;
anim();
startRecording();

function startRecording() {
  const chunks = []; // here we will store our recorded media chunks (Blobs)
  const stream = canvas.captureStream(); // grab our canvas MediaStream
  const rec = new MediaRecorder(stream); // init the recorder
  // every time the recorder has new data, we will store it in our array
  rec.ondataavailable = e => chunks.push(e.data);
  // only when the recorder stops, we construct a complete Blob from all the chunks
  rec.onstop = e => exportVid(new Blob(chunks, {type: 'video/webm'}));
  
  rec.start();
  setTimeout(()=>rec.stop(), 3000); // stop recording in 3s
}

function exportVid(blob) {
  const vid = document.createElement('video');
  vid.src = URL.createObjectURL(blob);
  vid.controls = true;
  document.body.appendChild(vid);
  const a = document.createElement('a');
  a.download = 'myvid.webm';
  a.href = vid.src;
  a.textContent = 'download the video';
  document.body.appendChild(a);
}

function anim(){
  x = (x + 1) % canvas.width;
  ctx.fillStyle = 'white';
  ctx.fillRect(0,0,canvas.width,canvas.height);
  ctx.fillStyle = 'black';
  ctx.fillRect(x - 20, 0, 40, 40);
  requestAnimationFrame(anim);
}
<canvas id="canvas"></canvas>


10
投票

您还可以使用 https://github.com/spite/ccapture.js/ 捕获为 gif 或视频。

© www.soinside.com 2019 - 2024. All rights reserved.