Mike
Mike

Reputation: 265

Canvas Animation - Stuck

I am trying to get to grips with canvas animation. I came across a great tutorial at http://www.kirupa.com/html5/creating_simple_html5_canvas_animation.htm (props!!) but I am trying to take this a little further by included user interaction, in the form of an input to specify the centre of the circle (I refer to it as "width" in the below code).

What I have tried is below and it works, to a certain degree. You will see the centre of the circle starts at 175. When I input anything above this, the circle does move to the right, as it should according to my code. I can then enter any number less than the current point and it will move to the left, as it should.

However!! After I have input the first figure, whether it be less or more than the start point, I then try to enter a figure larger than the current point and the circle just disappears.

I am baffled and after an explanation for why this is happening and a possible solution... if possible.

Thanks in advance, the code I have is...

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);

    }

}

Upvotes: 0

Views: 158

Answers (1)

Sebastian Simon
Sebastian Simon

Reputation: 19475

Solution: convert the string to a number:

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

Explanation: let’s examine the types in the code:

An input’s value will always be a string:

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

This equality operator disregards the type: 60 == '60' is as true as 60 == 60:

start == width

Only === will take the type into account as well. Next, the < operator implicitly converts any string into a number when comparing numbers with numbers as strings: '60' < 62 is true, '60' < 58 is false:

start < width

Next up, we’ve got an assignment that adds (or subtracts) 1 to start. This is not an issue as long as start is a number:

start += 1

And at some point start == width will become true and then this horrible thing happens:

start = width

From now on start is a string, because so is width. == will still work, < will still work, but…

start += 1

This will attempt to add a string and a number. Because JavaScript’s result of such an operation is always a string it will instead implicitly convert the number into a string and thus perform a string concatenation: '60' + 1 === '601'. Repeat this a few times and you end up with '6011111111111111111111111111111' and so on.

To prevent this from happening, refer to the solution at the top of this answer: convert the string to a number first.

Upvotes: 2

Related Questions