HTML5 / Javascript超时无法完成功能

时间:2012-02-13 02:51:18

标签: javascript html5 function loops timeout

我做了一个循环功能来慢慢淡化图像。

var ctx; // this is the canvas already defined
function nextPic(i)
    {
        trans = 1; //resets transparent var to 1
        fadeloop('out'); //starts loop
        ctx.clearRect(0, 0, canvas.width, canvas.height); //clears canvas, this doesn't work
        alert("done"); //this doesn't work either

    }
    function fadeloop(f){ //loop that fades
        if(f == 'out'){ //make sure it wants to shade out
            setTimeout(function () { //timed delay for fading out
                fadeImgOut(); //calls function to fade out by .01
                if(trans>0.0){ //if faded out break out of loop
                    fadeloop('out'); //if not restart function
                }
            },10);
        }
    }
    function fadeImgOut(){ //function that fades out
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img,0,0);
        ctx.globalAlpha = trans;
        trans = trans - .01;
    }

按钮调用nextpic。它将慢慢透明图像然后淡入另一个。现在它将图像淡出,直到trans = .01。不会继续警告("完成")或画布重置。我一遍又一遍地看着它,并且不知道该怎么做。

3 个答案:

答案 0 :(得分:1)

我测试了类似的功能。代码是:



    var j = 100;
    (function(){
        a();  // step 1;
        alert("hello world!"); // step 3; Fired without almost no time delay.
    })()

    function a(){
        setTimeout(function(){
           b();
           if(j>1){
              a();
           }
        }, 10); // step 2;  push the callback into a queue, and a() ends. 
    }

    function b(){
        if(j > 1){
            j--;
        }
    }

结果是:立即触发警报而没有任何延迟。结果是对的。

因为 setTimeout是异步函数。这意味着当a()第一次执行时,setTimeout中的回调函数将被推送到等待触发的队列。然后触发expression function中的alert()。

我不知道为什么你的警报没有被解雇。可能发生了一些错误。

答案 1 :(得分:0)

这可能无法解决您的问题,但可能会稍微简化一下。

您正在递归使用fadeloop,但您可以通过while循环完成此操作,这样可以更轻松地进行跟踪/调试。而且不必弄​​清楚你的递归内部有多深。

我能想到的唯一问题是setTimeout有setTimeout(函数,时间)的方法签名吗?其他一切看起来都是正确的。

答案 2 :(得分:0)

三位一体的答案是正确的,虽然没有发出警报确实让你听起来有一些其他错误干扰了发布的代码。 FWIW,这是一个包含代码的最小页面,表明它的工作原理如下:

<!doctype html>
<canvas id="canvas"></canvas>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = nextPic;
img.src = 'http://cdn.sstatic.net/careers/ads/img/careers2-ad-header-so-crop.png';

function nextPic(i) {
  trans = 1; //resets transparent var to 1
  fadeloop('out'); //starts loop
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  alert("done");
}
function fadeloop(f){ //loop that fades
  if(f == 'out'){ //make sure it wants to shade out
    setTimeout(function () { //timed delay for fading out
      fadeImgOut(); //calls function to fade out by .01
      if(trans>0.0){ //if faded out break out of loop
        fadeloop('out'); //if not restart function
      }
    },10);
  }
}
function fadeImgOut(){ //function that fades out
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(img,0,0);
  ctx.globalAlpha = trans;
  trans = trans - .01;
}
</script>

请注意你订购事物的方式(你在绘图后从trans中减去然后检查你是否应该重复循环),你将在.01附近结束是正确的。你需要重新排序以确保你达到0。

还要注意重复的浮点减法:你没有达到你认为的值(并且你永远不会在这个循环中达到0)。一个非常小的变化会让你开始正确(这假设你的图像已被绘制一次,因此可以在调用fadeImgOut之前从trans中减去):

function fadeloop(f){ //loop that fades
  if(f == 'out'){ //make sure it wants to shade out
    setTimeout(function () { //timed delay for fading out
      trans = Math.max(0, trans - .01);
      fadeImgOut(); //calls function to fade out by .01
      if(trans>0.0){ //if faded out break out of loop
        fadeloop('out'); //if not restart function
      }
    },10);
  }
}
function fadeImgOut(){ //function that fades out
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.globalAlpha = trans;
  ctx.drawImage(img,0,0);
}