带有.clearRect(x,y,w,h)的画布动画

时间:2013-10-07 11:15:00

标签: c# javascript animation canvas

我是使用javascript和canvas的相对初学者。我会试着解释一下到目前为止我做了什么。我有一个外部样式表,我设置了画布元素的背景(它是一条落在地平线上的道路的背景图像)。然后我创建了第一个函数(drawRoad()),在道路中心绘制一条白色的细条,然后沿着道路进入地平线。然后我创建了另一个在此白色条带中插入空格的函数(roadLines())。到目前为止,我很满意它的样子。

我现在要做的是运行一个循环... drawRoad(),然后是roadLines(),然后清除画布,然后再次使用drawRoad(),然后更改roadLines()的位置并调用再次这个功能。我想将roadLines()的位置垂直向下移动,以便它能够在路上行驶。 (我希望这有道理吗?)我是否正确地采用了这种方式?或者有一个更简单的方法,我完全忽略了吗?

我们非常感谢任何建议。以下是我到目前为止所做的事情。此外,函数animate()位于底部,但它所做的只是调用drawRoad()然后调用roadLines()。

window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function (callback) {
    window.setTimeout(callback, 1);
};})();

// set function that draws in the canvas
function drawRoad() {
    var myCanvas = document.getElementById("myCanvas");
    var ctx = myCanvas.getContext("2d");
    ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
    ctx.beginPath();
    ctx.moveTo(471, 199);
    ctx.lineTo(467, 600);
    ctx.lineTo(475, 600);
    ctx.closePath();
    ctx.fillStyle = "rgb(255, 255, 255)";
    ctx.fill();
    ctx.lineWidth = 1;
    ctx.strokeStyle = "rgb(255, 255, 255)";
}

//set variables and function/for loop that creates the spacing/intervals for road markings and movement
function roadLines() {
var interval = 1;
var space = 1;
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
for (var roadLine = 199; roadLine < 600; roadLine = roadLine + interval) {
    interval = (interval * 1.1);
    space = (space * 1.05);
    ctx.clearRect(450, roadLine, 40, space);
    }
}

function animate() {
    drawRoad();
    roadLines();
}

1 个答案:

答案 0 :(得分:2)

你需要做的第一件事就是让动画循环做一个循环。现在它只是调用你的两个函数然后退出,所以首先调整可以是:

function animate() {
    drawRoad();
    roadLines();

    requestAnimationFrame(animate); /// enable a loop
}

(ps:请确保将多边形填充从requestAnimFrame重命名为requestAnimationFrame,请参阅下面的演示链接。)

我们当然还需要启动动画循环,所以我们只需从全局范围调用它:

animate();

接下来我们需要确定的是你的线条正在移动,所以我们可以看到它们的动画效果。

现在只需提供一个偏移代码即可直接使用,因为您没有绑定到任何屏幕几何体的缩放。

当您尝试通过重置偏移来循环时,这将使线条“跳跃”,或者如果您选择不重置偏移量,则线条的大小会随着循环运行的时间而增大。

所以你必须重新考虑如何画线或做出妥协。

为了妥协,您需要在重置偏移循环的位置找到“最佳位置”值。线移动越慢,小“跳跃”就越明显。

为了使线条显得平滑,您需要实现一些简单的3D投影(或类似于您已经拥有但必须显示的2.5D伪3D)。

Here is an online demo 现在使用偏移设置动画线。我在底部添加了一个滑块,因此您可以找到偏移限制的最佳位置。试一试,看看它是如何工作的。我没有实现3D线的投影但是使用了你已经拥有的东西,但我有基于帖子的感觉,理解基本的这将是第一步。