我为我的背景制作了一个网格。我能够在X和Y上使用for循环制作一个网格来绘制正方形。
有没有办法让网格动画在两个轴上使用+ = 1在x和y上移动?
我正在考虑将网格划分为一个大图层并为图层设置动画,而不是为每个正方形设置动画。
http://jsbin.com/emexaz/1/edit
编辑:我正在尝试使用context.translate。但是每秒的每个间隔(假设setInterval的毫秒为1000),它会使值翻倍。
答案 0 :(得分:2)
以下是如何在画布中循环网格
绘制移动网格有多种方法。这是其中之一。
这是代码和小提琴:http://jsfiddle.net/m1erickson/AjZhD/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var w=canvas.width;
var h=canvas.height;
var offsetX=0;
var offsetY=0;
var rectX=0;
var rectY=0;
setInterval(function(){drawGrid();},100);
function drawGrid(){
// move the grid
offsetX+=5;
offsetY+=5;
if(offsetX==20){offsetX=0;}
if(offsetY==20){offsetY=0;}
rectX+=5;
rectY+=5;
if(rectX==w){rectX=0;}
if(rectY==h){rectY=0;}
ctx.save();
ctx.clearRect(0,0, w, h);
ctx.strokeStyle="gray";
ctx.beginPath();
// vertical grid lines
for(var x=offsetX;x<w;x+=20){
ctx.moveTo(x,0);
ctx.lineTo(x,h);
}
// horizontal grid lines
for(var y=offsetY;y<h;y+=20){
ctx.moveTo(0,y);
ctx.lineTo(w,y);
}
// "moving" rect
ctx.fillStyle="red";
ctx.rect(rectX-4,rectY-4,8,8);
ctx.stroke();
ctx.fill();
ctx.restore();
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
[编辑有关代码如何工作的详细信息]
可以......这里有更详细的解释。
这些var将让我们在画布上向右移动网格线。它们告诉我们在哪里绘制网格的下一帧和下一个红色矩形:
var offsetX=0;
var offsetY=0;
var rectX=0;
var rectY=0;
然后setInterval是一个每100毫秒调用一次drawGrid()的循环。
BTW,Loktar完全正确,除了快速测试之外,你还需要使用requestAnimationFrame而不是setInterval。 requestAnimation frame内置了优化功能,可以提高性能并减少资源使用。 // repease drawGrid() every 100 milliseconds
setInterval(function(){drawGrid();},100);
在drawGrid()中,我们增加offsetX / Y和rectX / Y,这使我们开始向右和向下绘制网格。请注意,移动20px后,网格基本上回到了相同的视觉位置,就像我们开始时一样!这允许我们简单地将我们的移动偏移重置为0并创建视觉错觉,即网格向右/向下行进超过1平方。然而,rectX / Y确实在网格上向右/向下继续(增加了运动的错觉)。
// move the grid
offsetX+=5;
offsetY+=5;
if(offsetX==20){offsetX=0;}
if(offsetY==20){offsetY=0;}
rectX+=5;
rectY+=5;
if(rectX==w){rectX=0;}
if(rectY==h){rectY=0;}
最后我们只绘制网格。首先我们绘制垂直线直到我们到达画布的末尾。然后是水平线。最后我们绘制了一个红色矩形,它创建了一个视觉错觉,网格向右/向下移动了超过1个网格。
for(var x=offsetX;x<w;x+=20){
ctx.moveTo(x,0);
ctx.lineTo(x,h);
}
// horizontal grid lines
for(var y=offsetY;y<h;y+=20){
ctx.moveTo(0,y);
ctx.lineTo(w,y);
}
// "moving" rect
ctx.fillStyle="red";
ctx.rect(rectX-4,rectY-4,8,8);
根据您想要的移动网格,有一些方法可以使网格更快更顺畅地飞行。 Loktar描述了使用requestAnimationFrame,它比setInterval做得更好。如果您想要非常快速和平滑,您可以简单地保存完整网格的图像并移动该图像,而不是重绘所有网格线。保存图像以便重用称为缓存。
如果您缓存的网格比画布宽1平方,高1平方,则可以重复使用视觉错误。你可以开始动画,超大的网格比画布更靠左,更远。然后使用每个动画帧,您将向右/向下移动网格1px。在20px之后,缓存的图像将与画布的顶部/左侧精确对齐。然后,您只需将缓存的网格移动到它的左侧和画布顶部的起始位置。然后重复动画!非常快,非常顺利。