如何使用该数据阵列从左到右移动画布?

时间:2013-10-10 11:26:07

标签: javascript html5 canvas html5-canvas

每次画布移动但不连续使用相同的数据数组?

如何使用该数据阵列从左到右移动画布线?

如果数据阵列完成,则使用相同的数据连续

这是我的代码:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <canvas id="canvas" width="160" height="160" style="background-color: black;"></canvas>
        <script type='text/javascript'>


            var canvas = document.getElementById("canvas");
            var ctx = canvas.getContext("2d");
            ctx.fillStyle ="#dbbd7a";
            ctx.fill();

            var fps = 1000;
            var n = 0;

            drawWave();
            var data = [
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
            ];

            function drawWave() {
                setTimeout(function () {
                    requestAnimationFrame(drawWave);
                    ctx.lineWidth="2";
                    ctx.strokeStyle='green';
                    ctx.clearRect(0, 0, canvas.width, canvas.height);

                    // Drawing code goes here
                    n += 1.5;
                    if (n > 200) {
                        n = 0;
                    }
                    ctx.beginPath();
                    for (var x = 0; x < n; x++) {
                        ctx.lineTo(x, data[x]);
                    }
                    ctx.stroke();

                }, 1000/fps);
            }

        </script>
    </body>
</html>

1 个答案:

答案 0 :(得分:2)

您的代码存在一些问题:

动画循环结束时非连续延迟的原因......

您的数组有140个元素,但您的代码正在尝试绘制200个元素。延迟是你的代码试图绘制(200-140)不存在的数组元素。

If(n>=data.length)     // not n>200 (there are only 140 data elements to process!)

使用fps间隔为1000的setTimeout是不可实现的(60fps是实际最大值)。

Var fps=60;   // not fps=1000 is too fast to be achieved

每次增加n 1.5。这将跳过您的一些数据元素。如果这不是你的意图,你应该将n增加1。

n+=1;    // not n+=1.5 which will skip some of your data[] elements

您正在清除画布并在每个动画循环中完全重绘波形。这样可行,但请保留以前的画布并添加其他行以绘制下一个[x,y]。只有在绘制完所有数据点后才能清除。

ctx.beginPath();
ctx.moveTo(n-1,data[n-1]);
ctx.lineTo(n,data[n]);
ctx.stroke();

这是一个小提琴:http://jsfiddle.net/m1erickson/vPXkm/

[根据OP的新信息添加]

在您进一步澄清后,我可能会理解您的愿望

我认为您希望波形图案从画布的左侧部分生成新图形,并使用动画将现有数据推向右侧。在从数据[]源绘制所有x,y之后,您希望绘图在数据[]的开头重复。

所以这就是你如何做到的:

  • 将画布调整为数据宽度的两倍[]。
  • 在画布上绘制两次数据。 (数据[0-140]然后再次数据[0-140])。
  • 将画布转换为图像。
  • 将画布调整为数据宽度[]。
  • 使用增加的偏移X在画布上为图像设置动画,以提供移动的幻觉。
  • 当图像用完时,请重置偏移。
  • 由于图像重复两次,因此此重置无缝显示。

这是新代码和另一个小提琴:http://jsfiddle.net/m1erickson/qpWrj/

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <body>
        <canvas id="canvas" width="560" height="160" style="background-color: black;"></canvas>
        <script type='text/javascript'>

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

            var data = [
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,
                148,149,149,150,150,150,143,82,82,82,82,82,82,82,148
            ];

            var fps = 30;
            var offsetX=-data.length*2;
            var waveImage;

            createWaveImage();

            function createWaveImage(){

                // make the canvas double data.length
                // and fill it with a background color
                canvas.width=data.length*2;
                ctx.fillStyle ="#dbbd7a";
                ctx.strokeStyle="green";
                ctx.lineWidth=2;
                ctx.fillRect(0,0,canvas.width,canvas.height);

                // plot data[] twice
                ctx.beginPath();
                ctx.moveTo(0,data[0]);
                for(var x=1; x<data.length*2; x++){
                    var n=(x<data.length)?x:x-data.length;
                    ctx.lineTo(x,data[n]);
                }
                ctx.stroke();

                // convert the canvas to an image
                waveImage=new Image();
                waveImage.onload=function(){
                    // resize the canvas to data.length
                    canvas.width=data.length;
                    // refill the canvas background color
                    ctx.fillStyle ="#dbbd7a";
                    ctx.fillRect(0,0,canvas.width,canvas.height);
                    // animate this wave image across the canvas
                    drawWave();
                }
                waveImage.src=canvas.toDataURL();
            }


            // animate the wave image in an endless loop
            function drawWave() {
                setTimeout(function () {
                    requestAnimationFrame(drawWave);

                    // Draw the wave image with an increasing offset
                    // so it appears to be moving
                    ctx.drawImage(waveImage,offsetX++,0);

                    // if we've run out of image, reset the offsetX
                    if((offsetX)>0){
                        offsetX=-data.length;
                    }

                }, 1000/fps);
            }

        </script>
    </body>
</html>