如何使用画布绘制一个能够向左移动的曲线?

4

我正在编写一个使用 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);
}

这个很好用:http://jsfiddle.net/HhGnb/。然而,现在我只能提供100像素的画布宽度,所以只有曲线最左边的100像素才能看到。http://jsfiddle.net/veEyM/1/。我想要实现这样的效果:当曲线的右端点大于画布的宽度时,整个曲线可以向左移动,这样我就可以看到曲线的最右端点,有点像曲线向左流动。我可以做到吗?

这有点棘手,因为画布不会记住你绘制的内容,而是像素颜色。每次都需要重新绘制整个图像。所以我会保存所有计算出来的点,并与它们一起工作。 - pimvdb
像这样:http://jsfiddle.net/veEyM/2/。 - pimvdb
@pimvdb,太好了,你能发一篇带有代码解释的答案吗? - wong2
1个回答

11
<canvas>元素的一个基本思想是,计算机“忘记”绘图命令,只保存像位图一样的像素。因此,要将所有内容向左移动,您需要清除画布并重新绘制所有内容。
还有一件事我想建议您注意-您总是从x = 0和y = 0开始,但显然在x = 0时,y不一定等于0。编辑:已实现此功能。
无论如何,最终我得到了这段代码:http://jsfiddle.net/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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接