在javascript中是否可以将for循环与setTimeOut结合起来?

在javascript中是否可以将for循环与setTimeOut结合起来?,javascript,Javascript,我很清楚我做错了什么。所有的字母一次打印出来。我想要一个HTML画布内的打字机效果。(最终,我希望字母沿着画布中的线条,但这是一个更大的难题。)我认为问题在for循环中,但我不确定如何解决它。。。感谢您的帮助 <html> <head> <style> canvas { border: 2px solid #f00; } </style> </head> <label>Your message here:</

我很清楚我做错了什么。所有的字母一次打印出来。我想要一个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>

帆布{
边框:2px实心#f00;
}
您的留言如下:

提交 var画布,ctx; 函数类型输出(str、startX、startY、线宽、填充){ var random=数学地板((数学随机()*100)+40); var cursorX=startX | | 0; var cursorY=startY | | 0; var lineHeight=lineHeight | | 32; 填充=填充| | 10; var i=0; 用于(i=0;i=canvas.width-padding){ cursorX=startX; 粗略+=线宽; } 如果(str.charAt(i)=='\n'| | str.charAt(i)=='\r'){ ctx.fillText(str.charAt(i),cursorX,cursorY); 设置超时(打印,20); cursorX=startX; }否则如果(str.charAt(i)=''){ ctx.fillText(str.charAt(i),cursorX,cursorY); 设置超时(打印,20); cursorX+=w; }else如果(str.charAt(i)==','| | str.charAt(i)=='。| | str.charAt(i)=='?'){ ctx.fillText(str.charAt(i),cursorX,cursorY); 设置超时(打印输出,220); cursorX+=w; }else如果(str.charAt(i)='@'){ ; 设置超时(打印输出,300); }否则{ ctx.fillText(str.charAt(i),cursorX,cursorY); 设置超时(打印,随机); cursorX+=w; } } } (document.getElementById('sub_btn')。onclick=function(){ canvas=document.getElementById('canvas'); ctx=canvas.getContext('2d'); ctx.fillStyle='#000000'; ctx.font='24px无衬线'; var str=document.getElementById('userInput')。值; 打字(str,25,25,32,10); })();
setTimeout()
不像“睡眠”功能。它不会暂停脚本。当你说:

setTimeout(typeOut, 220);
您的意思是“在220ms内安排另一个调用
typeOut()
,同时像以前一样继续执行
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();
}

示例代码笔:

您必须给出比“不起作用”更多的内容。控制台有什么说明吗?预期输出与实际输出的对比是什么?在JSFIDLE上设置一个实时示例来说明您的问题。由于for循环是同步的,但setTimeout是异步的,所以字母将立即打印出来,一个解决方案是使用for loo的i值p以增加超时的延迟iteration@tryingToGetProgrammingStraight如果
startX
为false,则将
0
赋值给
cursorX
。@tremstat使用递归函数(就像您几乎在使用setTimeout一样)而不是循环。延迟一段时间后,将迭代器传递给函数的下一个调用,然后完全删除for循环。@RUJordan,预期的输出是打字机效果。实际输出是一次到达的所有字母。没有“错误”“这将出现在控制台中,setTimeOut只是没有延迟功能。@Chad thnx for urhelp@tremstat您可能还希望跟踪变量中的超时,因此可以通过调用
clearTimeout()
取消图形。