3

我很清楚在这里做错了什么。所有的字母一次打印出来。我想要 HTML 画布中的打字机效果。(最终,我希望字母跟随画布中的一条线,但这是一个更大的难题。)我认为问题出在 for 循环中,但我不知道如何解决它......任何帮助赞赏!

<html>
<head>
<style>
canvas {
    border: 2px solid #f00;
}
</style>
</head>

<label>Your message here:</label>
<br>
<input class="textBox" style="width: 50em; height: 2em;"  id="userInput" />
<button id="sub_btn">Submit</button>

<body>
<canvas width="360" height="400" id="canvas"></canvas>

<script type="text/javascript"> 

var canvas, ctx;

function typeOut(str, startX, startY, lineHeight, padding) {
    var random = Math.floor((Math.random()*100)+40);
    var cursorX = startX || 0;
    var cursorY = startY || 0;
    var lineHeight = lineHeight || 32;
    padding = padding || 10;
    var i = 0;

    for (i = 0; i <= str.length; i++){

    var w = ctx.measureText(str.charAt(i)).width;
    if(cursorX + w >= canvas.width - padding) {
            cursorX = startX;
            cursorY += lineHeight;
        }

    if (str.charAt(i) === '\n' || str.charAt(i) === '\r'){
            ctx.fillText(str.charAt(i), cursorX, cursorY);
            setTimeout(typeOut, 20);
            cursorX = startX;
    } else if (str.charAt(i) === ' '){
            ctx.fillText(str.charAt(i), cursorX, cursorY);
            setTimeout(typeOut, 20);
            cursorX += w;
    } else if (str.charAt(i) === ',' || str.charAt(i) === '.' || str.charAt(i) === '?'){
            ctx.fillText(str.charAt(i), cursorX, cursorY);
            setTimeout(typeOut, 220);
            cursorX += w;
    } else if ( str.charAt(i) === '@') {
            ;
            setTimeout(typeOut, 300);
    } else {
            ctx.fillText(str.charAt(i), cursorX, cursorY);
            setTimeout(typeOut, random);
            cursorX += w;
    }
  }
}

(document.getElementById('sub_btn').onclick = function() {
    canvas = document.getElementById('canvas');
    ctx = canvas.getContext('2d');
    ctx.fillStyle = '#000000';
    ctx.font = '24px sans-serif';
    var str = document.getElementById('userInput').value;
    typeOut(str, 25, 25, 32, 10 );

})();

</script>
</body>
</html>
4

1 回答 1

3

setTimeout()不像“睡眠”功能。它不会暂停脚本。当你说:

setTimeout(typeOut, 220);

你是说“typeOut()在 220 毫秒内安排另一个调用,同时像以前一样继续for循环。

您想处理一个字符,然后调用一个延续函数(以正确的间隔)来处理下一个。就像是:

function typeOut(str, startX, startY, lineHeight, padding) {
    var random = Math.floor((Math.random()*100)+40);
    var cursorX = startX || 0;
    var cursorY = startY || 0;
    var lineHeight = lineHeight || 32;
    padding = padding || 10;
    var i = 0;

    // this will be called once per character
    var processNext = function() {
      if (i >= str.length)
        return;
      var timeout = random;

      var w = ctx.measureText(str.charAt(i)).width;
      if(cursorX + w >= canvas.width - padding) {
            cursorX = startX;
            cursorY += lineHeight;
      }

      if (str.charAt(i) === '\n' || str.charAt(i) === '\r'){
            ctx.fillText(str.charAt(i), cursorX, cursorY);
            timeout = 20;
            cursorX = startX;
      } else if (str.charAt(i) === ' '){
            ctx.fillText(str.charAt(i), cursorX, cursorY);
            timeout = 20;
            cursorX += w;
      } else if (str.charAt(i) === ',' || str.charAt(i) === '.' || str.charAt(i) === '?'){
            ctx.fillText(str.charAt(i), cursorX, cursorY);
            timeout = 220;
            cursorX += w;
      } else if ( str.charAt(i) === '@') {
            timeout = 300;
      } else {
            ctx.fillText(str.charAt(i), cursorX, cursorY);
            cursorX += w;
      }

      ++i;

      setTimeout(processNext, timeout);
    };

    // now start typing
    processNext();
}

示例 CodePen:http ://codepen.io/paulroub/pen/EDqok

于 2013-09-23T21:25:31.837 回答