画布有更新问题

时间:2014-07-20 02:46:11

标签: javascript html canvas text updating

<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"> 

<script type="text/javascript">
 window.onload = function() {
var ctx = document.getElementById("ctx").getContext("2d"); 
    function createText(words) {
     var LENGTH = words.length;
     var LOOPS = LENGTH;
     var reader = 0;

     position = 10;
     while( LOOPS > 0) {
     letter = words.substr(reader,1);

     setTimeout(ctx.fillText(letter,position,10),100); 
     position += 6; 
     reader += 1; 
     LOOPS -= 1; 
      }

    }


    createText("Hello, how are you?");      

    }
</script>


</canvas> 

我希望它有点像打字动画,它在打印每个字母之前暂停了几分之一秒,但它会同时加载所有字母。我做错了什么?

1 个答案:

答案 0 :(得分:2)

所以有一些事情使得这对你不起作用,因为setTimeout你的ctx.fillText被立即调用,一旦循环击中它。要停止它,您需要将其包装在function中,以便在超时期间调用它。

setTimeout(function(){
    // your logic here.
}, 100);

但是,如果你这样做,你将遇到常见问题,你只能获得最后字母due to the way variable scoping works in JavaScript。要解决此问题,您需要将函数包装在闭包中并将值传递给它。

// loop start
 a++;
 b++;
 setTimeout(
    (function (a,b) {
         return function () {
             // some logic that uses a and b
         }
 })(a, b), 100);
// loop end

最后发生的事情是你的超时设置为100 ..所以它一下子就会发生。这意味着每个超时将在100ms后触发,因为创建循环非常快。为了解决这个问题,你需要在某处保存延迟并在循环中增加延迟,以便它们相继发生。例如,第一个将延迟100毫秒,下一个将延迟200毫秒,然后是300,等等。

// loop start
 a++;
 b++;
 // Increase the time delay each loop iteration
 timeDelay += 100;

 setTimeout(
    (function (a,b) {
         return function () {
             // some logic that uses a and b
         }
 })(a, b), timeDelay);
// loop end

完整的工作代码和演示

<强> Live Demo

 window.onload = function () {
     var ctx = document.getElementById("ctx").getContext("2d");

     function createText(words) {
         var LENGTH = words.length;
         var LOOPS = LENGTH;
         var reader = 0;
         var timeDelay = 100;

         position = 10;

         while (LOOPS > 0) {
             letter = words.substr(reader, 1);

             setTimeout((function (letter, position) {
                 return function () {
                     ctx.fillText(letter, position, 10);
                 }
             })(letter, position), timeDelay);

             position += 6;
             reader += 1;
             LOOPS -= 1;
             timeDelay += 100;
         }

     }

     createText("Hello, how are you?");

 }