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