Canvas 动画 - 卡住

Canvas Animation - Stuck

我正在努力掌握 canvas 动画。我在 http://www.kirupa.com/html5/creating_simple_html5_canvas_animation.htm 遇到了一个很棒的教程(props!!),但我试图通过包含的用户交互更进一步,以指定圆心的输入形式(我指的是它如下面代码中的 "width")。

下面是我尝试过的方法,在一定程度上有效。您会看到圆心从 175 开始。当我在这个上方输入任何内容时,圆确实会向右移动,根据我的代码应该如此。然后我可以输入任何小于当前点的数字,它会向左移动,就像它应该的那样。

但是!!在我输入第一个数字后,无论是小于还是大于起点,然后我尝试输入一个大于当前点的数字,圆圈就消失了。

我很困惑,在解释了为什么会发生这种情况以及可能的解决方案之后……如果可能的话。

提前致谢,我的代码是...

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var requestAnimFrame = window.requestAnimationFrame ||
                       window.mozRequestAnimationFrame ||
                       window.webkitRequestAnimationFrame ||
                       window.msRequestAnimationFrame;

var start = 175;
var startH = 250;
var radius = 175;

ctx.beginPath();

ctx.arc(start, startH, radius, 0, Math.PI * 2, false);
ctx.closePath();

ctx.fillStyle = "#006699";
ctx.fill();

function drawCircle() {
    var width = document.getElementById("width").value;

    if(start == width) {
        start = width;          

    } else {
        ctx.clearRect(0, 0, canvas.height, canvas.width);

        ctx.beginPath();

        ctx.arc(start, startH, radius, 0, Math.PI * 2, false);
        ctx.closePath();

        ctx.fillStyle = "#006699";
        ctx.fill();

        if(start < width) {
            start += 1;
        } else {
            start -= 1;
        }

        requestAnimFrame(drawCircle);

    }

}

解决方法:将字符串转为数字:

var width = Number(document.getElementById("width").value);

解释:让我们检查代码中的类型

一个输入的值总是一个字符串:

width = document.getElementById("width").value;

此相等运算符忽略类型:60 == '60'60 == 60 一样为真:

start == width

只有 === 也会考虑类型。接下来,< 运算符在将数字与数字作为字符串进行比较时隐式地将任何字符串转换为数字:'60' < 62 为真,'60' < 58 为假:

start < width

接下来,我们有一个将 1 添加(或减去)到 start 的作业。这不是问题,只要 start 是一个数字:

start += 1

并且在某个时候 start == width 会变为真,然后这可怕的事情发生了:

start = width

从现在开始 start 是一个 字符串 ,因为 也是 width== 仍然有效,< 仍然有效,但是……

start += 1

这将尝试添加一个字符串和一个数字。因为 JavaScript 这种操作的结果总是 string 它会 隐式地将数字转换为 string 从而执行字符串 连接'60' + 1 === '601'。重复几次,最后得到 '6011111111111111111111111111111' 等等。

为防止这种情况发生,请参考本答案顶部的解决方案:先将字符串转换为数字。