<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>
我希望它有点像打字动画,它在打印每个字母之前暂停了几分之一秒,但它会同时加载所有字母。我做错了什么?
答案 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?");
}