动画图像数组滞后

Lag in animated image array

本文关键字:滞后 数组 图像 动画      更新时间:2023-09-26

我正在制作一个由不断变化的图像数组(基于此)制作的循环动画(如动画GIF)。动画通过不断变化的图像类推进。以下是我目前的内容:

function animateEverything() {
var imgc = 0;
var frame1 = $('.start').attr('src');
var frame2 = $('.start').prev().attr('src');
var frame3 = $('.start').prev().prev().attr('src');
var frame4 = $('.start').prev().prev().prev().attr('src');
var frame5 = $('.start').prev().prev().prev().prev().attr('src');
var images = [frame1,frame2,frame3,frame4,frame5];
$("#ball").html("<img src='" +images[0] +"'>").show()
setTimeout(setImage, 50);
function setImage() {
    var next=new Image()
    images.push(images.shift())
    next.onload=function(){
        $("#ball img").attr("src", this.src)
    }
    next.src= images[0] 
    setTimeout(setImage, 500);   
}   
// MOVE FORWARD     
setInterval(function(){
$('.start').removeClass('start').next().addClass('start');
frame1 = $('.start').attr('src');
frame2 = $('.start').prev().attr('src');
frame3 = $('.start').prev().prev().attr('src');
frame4 = $('.start').prev().prev().prev().attr('src');
frame5 = $('.start').prev().prev().prev().prev().attr('src');
images = [frame1,frame2,frame3,frame4,frame5];
},10000);
}
animateEverything();    

一切都很好,除了当类改变时有延迟。我试着摆弄setTimeout持续时间,但它似乎没有帮助…不知道还能试什么

关于如何消除延迟有什么想法吗?

这里的

jsfiddle

首先需要缓存加载和解码的图像。每次加载图像都需要浏览器(重新)从网络中获取原始二进制压缩图像文件,如果幸运的话,也可以从缓存中获取。然后需要对其进行解码,解压缩,并将其转换为RGBA位图,从这一点可以显示出来。

这个过程可能比动画所需的16.7-33.4ms(分别为60/30fps)要长。每次设置src时,都会在后台启动加载进程。

所以更合适的方式是:

  • 首先加载背景中的所有图像。图像加载是异步的,所以你必须使用onload处理程序来处理这个问题。你应该为此创建一个单独的处理程序,并在图像正确加载后更新帧数组。

  • 不要使用setInterval/setTimeout。这些是不准确的,对于动画来说非常不准确。相反,使用requestAnimationFrame,它可以与监视器更新完美同步。

所以本质上你需要:

  • 一个包含要加载的url的数组,这些url被馈送到:
  • 处理异步加载的图像加载器
  • 当图像加载时更新帧数组
  • 使用requestAnimationFrame
  • 在帧数组中动画(预加载)图像

对于Javascript中的动画,通常使用setTimout比setInterval更容易。最好让一个函数连续调用实现动画的函数,而不是使用多个setinterval来驱动动画。

Javascript应该是这样的:

$("#ball").html("<img src='" +images[0] +"'>").show()
setInterval(setImage, 50);
function setImage() {
  var next=new Image()
  images.push(images.shift())
  next.onload=function(){
    $("#ball img").attr("src", this.src)
  }
  next.src= images[0]   
}  

这是一把可以工作的小提琴。我看不出是否有明显的延误。

https://jsfiddle.net/4bb0wwsz/

感谢您的帮助,我最终接受了Rob Scott的建议,并切换到css动画的闪烁效果,仍然使用jquery的图像推进

css:

img {
width:0;
height:0;
position:absolute;
top:0;
left:0;
    -webkit-animation-name: flash;
    -webkit-animation-duration: 1s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-direction: normal;
    -webkit-animation-fill-mode:forwards;
    -webkit-animation-timing-function:steps(1, end);
}
.first, .second, .third, .fourth, .fifth {
display:block;width:100%;height:auto;}
.first {-webkit-animation-delay:0s;}
.second {-webkit-animation-delay:0.2s;}
.third {-webkit-animation-delay:0.4s;}
.fourth{-webkit-animation-delay:0.6s;}
.fifth{-webkit-animation-delay:0.8s;}
@-webkit-keyframes flash {0% {opacity: 1;}20% {opacity: 0;}100% {opacity: 0;}}

js:

// MOVE FORWARD 
$('.fifth').prev().addClass('fourth');
$('.fourth').prev().addClass('third');
$('.third').prev().addClass('second');
$('.second').prev().addClass('first');
setInterval(function(){ 
$('.fourth, .third, .second, .first').attr('class','');
$('.fifth').removeClass('fifth').next().addClass('fifth');
$('.fifth').prev().addClass('fourth');
$('.fourth').prev().addClass('third');
$('.third').prev().addClass('second');
$('.second').prev().addClass('first');
},10000);
http://jsfiddle.net/milpool/et05pvw5/