0

我是一个非常初学者的网页设计师,我对这段代码有两个问题。

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#canvas1{border: #666 3px solid;}
</style>
<script type="application/javascript" language="javascript">
function draw (x,y){
var canvas = document.getElementById('canvas1');
var ctx = canvas.getContext('2d');
ctx.save();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillstyle = "rgb (0,200, 0)";
ctx.fillRect(x, 20, 50, 50);
ctx.restore();
x += 5;
var loop = setTimeout('draw('+x+', '+y+')', 100); 
}
</script>
</head>
<body>
<button onclick="draw(0,0)">Start</button>
<canvas id="canvas1" width="400" height="400"</canvas>
</body>
</html>

为什么方块总是变黑?为什么如果我再次尝试按开始,clearRect 功能不起作用?

4

2 回答 2

0

因为你需要使用:

ctx.fillStyle = "rgb(0,200,0)";

大写“S”,“rgb”和左括号之间没有空格:http: //jsfiddle.net/dtHjf/

然后,关于为什么多次按下“开始”会导致方块闪烁,那是因为每次按下它都会开始另一个动画循环,但没有取消旧的循环,所以你有多个循环与彼此。如果您确保在开始新循环之前取消任何预先存在的循环,您应该没问题:

http://jsfiddle.net/dtHjf/2/

HTML

<button id="startAnim">Start</button><br />
<canvas id="canvas1" width="400" height="400"></canvas>

JS

var canvas = document.getElementById('canvas1'),
    ctx = canvas.getContext('2d'),
    loop;

function draw(x, y) {

    ctx.save();
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "rgb(0,200,0)";
    ctx.fillRect(x, 20, 50, 50);
    ctx.restore();

    x += 5;
    loop = setTimeout(function(){draw(x,y)}, 100);
}

document.getElementById('startAnim').onclick = function(){
    clearTimeout(loop);
    draw(0,0);
};

此外,这与您的问题无关,但您可能想看看requestAnimationFrame

https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

于 2013-11-02T14:44:50.003 回答
0

当您单击开始时,您将开始一个与已经开始的循环并行运行的新循环,并且取决于首先执行的循环,您的画布将被清除并填充两次(或者您启动循环的次数 - 闪烁越明显将会)。

您需要一种机制来防止循环多次启动。一种方法是使用标志。我还建议您重构代码,将循环和绘图分开:

现场演示在这里

/// put these outside, no need to re-allocate them each time
var canvas = document.getElementById('canvas1');
var ctx = canvas.getContext('2d');
var w = canvas.width;
var h = canvas.height;
var x = 0;
var isRunning = false;

/// all loop-related here:
function loop() {

    /// call draw from inside the loop instead
    draw(x, 0); /// you are never using y so I just set 0 here...

    x += 5;

    if (isRunning && x <= w) {
        requestAnimationFrame(loop);  /// this is a better alternative
        //setTimeout(loop, 100);      /// optionally, but not recommended
    } else {
        isRunning = false;  /// box is outside visible area so we'll stop..
    }
}

/// keep draw() "clean", no loop code in here:
function draw(x, y) {
    /// no need for save/restore here...
    ctx.clearRect(0, 0, w, h);
    ctx.fillStyle = "rgb(0, 200, 0)";
    ctx.fillRect(x, 20, 50, 50);
}

fillStyle的输入错误,您rgb(...必须没有空格(如另一个答案中所述 - 但在这种情况下只会导致填充样式为黑色),此外您canvas在 html 中缺少标签的右括号。

要检查按钮点击,这是一种更推荐的方法,而不是在 html 中内联 JS:

/// check for button clicks (start):
document.getElementById('start').addEventListener('click', function() {

    if (!isRunning) {     /// are we running? if not start loop
        isRunning = true; /// set flag so we can prevent multiple clicks
        x = 0;            /// reset x
        loop();           /// now we start the *loop*
    }

}, false);

在你的 html 中:

<button id="start">Start</button>

现在您可以轻松制作暂停按钮:

<button id="stop">Stop</button>

并将其添加到脚本中:

document.getElementById('stop').addEventListener('click', function() {

    isRunning = false;

}, false);
于 2013-11-04T06:15:52.097 回答