在画布上平稳地从A点移动到B点
Moving object from A to B smoothly across canvas
我正在尝试使用HTML画布和常规javascript平滑地从A点移动对象到B点。
点A是坐标集合
点B为光标所在位置。
我做了一个jsfiddle: https://jsfiddle.net/as9fhmw8/
while(projectile.mouseX > projectile.x && projectile.mouseY < projectile.y)
{
ctx.save();
ctx.beginPath();
ctx.translate(projectile.x, projectile.y);
ctx.arc(0,0,5,0,2*Math.PI);
ctx.fillStyle = "blue";
ctx.fill();
ctx.stroke();
ctx.restore();
if(projectile.mouseX > projectile.x && projectile.mouseY < projectile.y)
{
var stepsize = (projectile.mouseX - projectile.x) / (projectile.y - projectile.mouseY);
projectile.x += (stepsize + 1);
}
if(projectile.mouseY < projectile.y)
{
var stepsize = (projectile.y - projectile.mouseY) / (projectile.mouseX - projectile.x);
projectile.y -= (stepsize + 1);
}
}
本质上我不能弄清楚的是让while循环变慢(这样它就会看起来像动画,而不是每次迭代都显示结果)。
我也不知道如何防止Arc复制,从而创建一条永久的线,而不是看起来从a点移动到b点。
这里的平滑动画实际上是关于确定每次循环迭代时对象移动的距离。
这里涉及到一点数学,但还不算太糟。
速度在你的例子中,速度就是粒子在一段时间内沿任何给定方向运动的速度。如果你想让你的粒子在4秒内移动200px
,那么速度将是50px / second
。
有了这些信息,你可以很容易地确定给定一段任意长度的时间,一个粒子需要移动(动画)多少像素。
pixels = pixelsPerSecond * seconds
知道要移动多少像素很好,但不能转换为单独的X和Y坐标。这就是向量的作用
向量数学中的向量是方向和大小的度量。就我们的目的而言,这就像将速度与角度(47°)结合起来。
向量的一个重要性质是它可以被分解成单独的X和Y分量(对于二维空间)
所以如果我们想要移动在50px / second
处的粒子以47°
的角度,我们可以这样计算一个向量:
function Vector(magnitude, angle){
var angleRadians = (angle * Math.PI) / 180;
this.magnitudeX = magnitude * Math.cos(angleRadians);
this.magnitudeY = magnitude * Math.sin(angleRadians);
}
var moveVector = new Vector(50, 47);
奇妙之处在于,这些值可以简单地添加到任何一组X和Y坐标中,以根据速度计算移动它们。
鼠标移动矢量
以这种方式建模你的对象有一个额外的好处,那就是使事情变得漂亮并且在数学上是一致的。粒子和鼠标之间的距离只是另一个矢量。
我们可以用更多的数学方法来计算距离和角度。还记得毕达哥拉斯吗?原来他很聪明。
function distanceAndAngleBetweenTwoPoints(x1, y1, x2, y2){
var x = x2 - x1,
y = y2 - y1;
return {
// x^2 + y^2 = r^2
distance: Math.sqrt(x * x + y * y),
// convert from radians to degrees
angle: Math.atan2(y, x) * 180 / Math.PI
}
}
var mouseCoords = getMouseCoords();
var data = distanceAndAngleBetweenTwoPoints(particle.x, particle.y, mouse.x, mouse.y);
//Spread movement out over three seconds
var velocity = data.distance / 3;
var toMouseVector = new Vector(velocity, data.angle);
顺利动画
以一种不笨拙的方式在屏幕上动画你的东西意味着做以下事情:
- 尽可能快地运行你的动画循环
- 确定距离上次 已经过了多少时间
- 根据经过的时间移动每个项目。
- 重新绘制屏幕
对于动画循环,我将使用requestAnimationFrame
API而不是setInterval
,因为它将具有更好的整体性能。
清空屏幕
当你重新绘制屏幕时,只要在整个屏幕上画一个大矩形,用任何你想要的背景颜色,然后再重新绘制你的项目。
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
把它放在一起
这里是一个小提琴演示所有这些技术:https://jsfiddle.net/jwcarroll/2r69j1ok/3/
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- 正在SharePoint 2013母版页中添加JQuery移动文件
- 如何在android中使用phonegap将文件从一个文件夹移动/复制到另一个文件夹
- 如何使用phaser使html5游戏在移动设备浏览器上运行
- FabricJs-限制主对象内添加对象的移动区域
- 如何从画布上的某个移动事件中获取X和Y
- 触摸移动时切换到新元素
- 每当您在选择器内移动鼠标时,悬停功能就会重复
- 停止jQuery UI滑块移动超过给定值
- 谷歌地图API v3不适用于移动浏览器或PhoneGap
- 如何将chrome扩展功能移植到移动设备(特别是jquery和trello)
- JQuery移动动态分区页面
- XMLHttpRequest在移动设备上的chrome上不起作用
- 如何使bxslider仅在移动视图中处于活动状态
- css停止图像在滚动中移动
- jquery移动对齐按钮取决于内容大小
- 背景图像顶部的滚动图像不移动
- 如何在react js中移动第二个组件
- DataTables在表之间移动行
- 当带有渲染器的DOM元素不在屏幕顶部时,移动了场景的坐标