【问题标题】:Improve HTML5 Canvas frame by frame JPG animation to fully cache before animating改进 HTML5 Canvas 逐帧 JPG 动画以在动画前完全缓存
【发布时间】:2012-12-03 23:08:13
【问题描述】:

我正在尝试在这个由 Phrogz 回答的出色脚本 here 之上构建。

问题是动画在所有图像都缓存在浏览器中之前不会播放。因此,在第一次加载时它不会播放。仅在重新加载时。

我尝试这样做的目的是尝试提供一种替代解决方案来让动画自动播放,因为该功能在 iOS 浏览器中不起作用。

这是我正在使用的代码:

         function draw() { 
            var imgNumber = 1;
            var lastImgNumber = 121;

            var ctx = canvas.getContext('2d');
            var img = new Image;
            img.onload = function(){
            ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height );
            ctx.drawImage( img, 0, 0 );
            };
            var timer = setInterval( function(){
              if (imgNumber>lastImgNumber){
                clearInterval( timer );
              }
             else{
                img.src = "jpg_80/t5_"+( imgNumber++ )+".jpg";
              }
            }, 1000/24 ); //Draw at 24 frames per second
          }

我尝试在结束正文标记之前添加这个:

                 window.onload = draw; 

但是,我认为必须在 draw() 函数中更改代码。在 setInterval 函数的某个地方?

【问题讨论】:

  • 要先加载全部121张图片,再启动动画吗?
  • 当你有一个 121 jpeg 帧的动画时,你应该使用 <video> 来代替。
  • @Philipp 是的,但是,关键是这个动画可以在 iOS 中自动播放。否则,我只会使用
  • @pimvdb 是的,预加载图像,然后开始动画。如果您在此链接上进行 iPhone 或 iPad 测试以查看我的问题。第一次请求时不加载:html5canvas.syntheticmedia.net

标签: ios caching animation html5-canvas autoplay


【解决方案1】:

这是您的 draw 函数的修改版本,它会在将所有图像放到画布上之前预加载它们。

假设您有一个 id 为“anim”的画布(因为您提供的源代码中没有画布的引用)

<canvas id='anim' width='660' height='500'></canvas>

JavaScript:(在 iPad 上测试)

function draw() {
    var ctx = document.getElementById('anim').getContext("2d");
    var start = 1, stop = 121,cur=start,imgArr=[];

    var loadLoop = function() {
        var img = document.createElement("img");
        img.onload = function() {
            imgArr.push(this);
            cur++;

            if(cur > stop) {
                // all images preloaded
                animate();
            }
            else {
                loadLoop();
            }
        }

        img.src = "jpg_80/t5_"+(cur)+".jpg";
    }

    loadLoop();

    function animate() {
        var timer = setInterval(function() {
            ctx.drawImage(imgArr.shift(), 0, 0 );
            if(imgArr.length == 0) {
                // no more frames
                clearInterval(timer);
            }
        },1000/24);
    }
}

【讨论】:

  • 你解决了!我已经尝试解决这个问题很长时间了。在 Safari 和 Chrome 中测试并在 iPad 上运行。谢谢!
【解决方案2】:

您可以创建 121 个 &lt;img&gt; 元素并为每个元素添加一个 .onload 函数。在那个处理程序中,你增加一个数字,当它达到 121 时,你开始动画。

但是您正在尝试做的事情听起来像是您想要创建一个视频剪辑。如果这是您的意图,&lt;video&gt; 标签可能是更好的解决方案。使用现代编解码器编码的 121 帧视频剪辑将比 121 个单独的 JPEG 小得多,因为视频压缩算法使用帧之间的冗余来改进压缩。

【讨论】:

  • 我将 121 张图片压缩到比 MP4 略大的位置。 MP4 为 2.2 mb,121 张图像为 2.8 mb。所以,大小不是问题。我知道这将发出 121 个 HTTP 请求,但是我会以这种方式缓存它们,它只需要执行一次。一旦它被缓存,动画就可以正常工作。即使在 iPhone 4s 上。
  • 我已经尝试在此处合并代码:stackoverflow.com/questions/7394136/… 认为您所说的将解决此问题,但尚未成功。有代码示例吗?
  • 如果我有答案,先生,我不会发布问题。我要求提供代码示例,因为您回答了这个问题,但是,它的答案不够具体,我无法接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-14
  • 1970-01-01
  • 2019-12-03
  • 2011-12-25
  • 2012-12-29
  • 2012-09-16
  • 1970-01-01
相关资源
最近更新 更多