admin管理员组

文章数量:1291343

I'm writing a program that will draw the sine curve with canvas.
HTML:

<canvas id="mycanvas" width="1000" height="100">
    Your browser is not supported.
</canvas>

JavaScript:

var canvas = document.getElementById("mycanvas");
if (canvas.getContext) {
    var ctx = canvas.getContext("2d");
    ctx.lineWidth = 3;
    var x = 0,
        y = 0;
    var timeout = setInterval(function() {
        ctx.beginPath();
        ctx.moveTo(x, y);
        x += 1;
        y = 50 * Math.sin(0.1 * x) + 50;
        ctx.lineTo(x, y);
        ctx.stroke();
        if (x > 1000) {
            clearInterval(timeout);
        }
    }, 10);
}

This works really nice: /

However, now I can only offer say 100px for the canvas width, so only the leftest 100px of the curve could be seen. /
I want to archive this effect: when the right point of the curve is bigger than the width of canvas, the whole curve could move left, so I can see the rightest point of the curve, it's a bit like the curve is flowing to left. Can I do that?

I'm writing a program that will draw the sine curve with canvas.
HTML:

<canvas id="mycanvas" width="1000" height="100">
    Your browser is not supported.
</canvas>

JavaScript:

var canvas = document.getElementById("mycanvas");
if (canvas.getContext) {
    var ctx = canvas.getContext("2d");
    ctx.lineWidth = 3;
    var x = 0,
        y = 0;
    var timeout = setInterval(function() {
        ctx.beginPath();
        ctx.moveTo(x, y);
        x += 1;
        y = 50 * Math.sin(0.1 * x) + 50;
        ctx.lineTo(x, y);
        ctx.stroke();
        if (x > 1000) {
            clearInterval(timeout);
        }
    }, 10);
}

This works really nice: http://jsfiddle/HhGnb/

However, now I can only offer say 100px for the canvas width, so only the leftest 100px of the curve could be seen. http://jsfiddle/veEyM/1/
I want to archive this effect: when the right point of the curve is bigger than the width of canvas, the whole curve could move left, so I can see the rightest point of the curve, it's a bit like the curve is flowing to left. Can I do that?

Share Improve this question edited Sep 30, 2011 at 11:06 pimvdb 155k80 gold badges311 silver badges356 bronze badges asked May 17, 2011 at 15:12 wong2wong2 35.8k51 gold badges137 silver badges182 bronze badges 3
  • That's tricky, since a canvas does not remember what you painted but rather the pixel colors. You'd need to redraw the whole image each time. So I'd save all points you calculated and work with them. – pimvdb Commented May 17, 2011 at 15:18
  • Like: jsfiddle/veEyM/2. – pimvdb Commented May 17, 2011 at 15:23
  • @pimvdb that's nice, could you post an answer with some explanation of the code? – wong2 Commented May 17, 2011 at 15:27
Add a ment  | 

1 Answer 1

Reset to default 11

One of the basic ideas of the <canvas> element is that the puter 'forgets' the drawing mands and only saves the pixels, like a bitmap. So to move everything to the left, you need to clear the canvas and draw everything again.

There is also one thing I'd like to advise you - you always start with x = 0 and y = 0, but obviously at x = 0 then y is not necessarily equal to 0 as well. EDIT: implemented this.

Anyway, I ended up with this code: http://jsfiddle/veEyM/5/

var canvas = document.getElementById("mycanvas");
var points = {}; // Keep track of the points in an object with key = x, value = y
var counter = 0; // Keep track when the moving code should start

function f(x) {
    return 50 * Math.sin(0.1 * x) + 50;
}

if (canvas.getContext) {
    var ctx = canvas.getContext("2d");
    ctx.lineWidth = 3;
    var x = 0,
        y = f(0);
    var timeout = setInterval(function() {
        if(counter < 100) { // If it doesn't need to move, draw like you already do
            ctx.beginPath();
            ctx.moveTo(x, y);
            points[x] = y;
            x += 1;
            y = f(x);
            ctx.lineTo(x, y);
            ctx.stroke();
            if (x > 1000) {
                clearInterval(timeout);
            }
        } else { // The moving part...
            ctx.clearRect(0, 0, 100, 100); // Clear the canvas
            ctx.beginPath();
            points[x] = y;
            x += 1;
            y = f(x);
            for(var i = 0; i < 100; i++) {
                // Draw all lines through points, starting at x = i + ( counter - 100 )
                // to x = counter. Note that the x in the canvas is just i here, ranging
                // from 0 to 100
                ctx.lineTo(i, points[i + counter - 100]);
            }
            ctx.stroke();
        }
        counter++;
    }, 10);
}

本文标签: javascriptHow to draw a curve that could move to left with canvasStack Overflow