到目前为止,您已经有了一个代码,您可以在其中在画布表面的某个位置绘制一个圆,很好,现在为了让它看起来像在移动,您必须继续绘制它一次又一次地稍微改变它的位置以赋予它平滑的运动效果,这是每秒绘制 60 次的标准(我认为这是因为每秒 60 帧是人眼可以注意到的最多的帧,或其他)。当然,每次你在另一个位置绘制它时,都需要清除旧的绘图。
让我们稍微修改一下你的代码,让它对动画友好:
<script type="text/javascript">
function init()
{
canvas = document.getElementById('canvas');
if(canvas.getContext)
context = canvas.getContext('2d');
else return;
setInterval(draw, 1000 / 60); // 60 times per second
}
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(150,29,28)";
// var startPoint = (Math.PI/180)*0; Kinda redundant, it's just 0
// var endPoint = (Math.PI/180)*360; Again, it's just PI times 2
context.beginPath();
context.arc(200, 200, 150, 0, Math.PI * 2, true);
context.fill();
context.closePath();
}
</script>
</head>
<body onload="init();">
<canvas id="canvas" width="500" height="500"></canvas><br>
现在有很多有趣的方法可以让物体向固定点移动,但最简单的当然是沿直线移动。为此,您需要
让我们更改您的代码,以便我们掌握这些代码
var canvas, context,
position = {x: 200, y: 200},
target = {x: 400, y: 400};
function init()
{
...
}
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(150,29,28)";
context.beginPath();
context.arc(position.x, position.y, 150, 0, Math.PI * 2, true);
context.fill();
context.closePath();
}
好!这样,每当您更改 position 对象中的某个值时,您的圆圈的位置都会受到影响。
如果你从目标位置减去当前位置,你会得到另一个向量,它直接指向来自当前位置的目标位置,对吧?因此,获取该向量并对其进行标准化,将其长度变为 1,结果实际上将是从目标到对象位置的角度的(余弦,正弦)。这意味着,如果您将该归一化向量添加到对象的当前位置,则对象将一次向目标位置移动 1 个单位。
对向量进行归一化就是简单地将其分量除以它的长度。
function normalize(v)
{
var length = Math.sqrt(v.x * v.x + v.y * v.y);
return {x: v.x / length, y: v.y / length};
}
var step = normalize({x: target.x - position.x, y: target.y - position.y});
好的,现在我们需要做的就是不断将step 向量添加到对象的当前位置,直到它到达目标位置。
function normalize(v)
{
var length = Math.sqrt(v.x * v.x + v.y * v.y);
return {x: v.x / length, y: v.y / length};
}
var canvas, context,
position = {x: 200, y: 200},
target = {x: 400, y: 400},
step = normalize({x: target.x - position.x, y: target.y - position.y});
function init()
{
canvas = document.getElementById('canvas');
if(canvas.getContext)
context = canvas.getContext('2d');
else return;
setInterval(draw, 1000 / 60);
}
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(150,29,28)";
context.beginPath();
context.arc(position.x, position.y, 150, 0, Math.PI * 2, true);
context.fill();
context.closePath();
position.x += step.x;
position.y += step.y;
}
你有它。当然这是非常基本的代码,你必须添加一个代码来检查对象是否已经到达目标,否则它会一直越过目标。如果它移动得太慢,只需按任意速度因子缩放step 向量。同样在现实世界的应用程序中,你会有很多对象,而不仅仅是一个圆圈,所以你必须让它完全面向对象,因为每个对象都有它的位置、目标位置、颜色等等等。一个库使用向量会派上用场。这是我前段时间为自己写的一篇:http://pastebin.com/Hdxg8dxn