看到基于Canvas动画的Google浮动小球效果,非常炫,决定自己尝试模仿着做一个。

Demo:http://qs20199.github.io/SuspendingBall/

这个Demo并不难,包含以下两个部分

  • 物理控制
  • 动画控制

物理控制

function Ball(posX,posY,color,radius){this.iOriginX=this.iCurX=posX;this.iOriginY=this.iCurY=posY;this.sColor=color;this.iRadius=radius;this.iDX=this.iDY=0;
}
  • OriginX/Y代表小球的原始位置
  • CurX/Y代表小球的实际位置。
  • dx和dy代表了小球在两个方向上的速度

小球控制有以下逻辑

  • 每一帧小球将移动dx/dy个像素
//移动
aBalls[i].iCurX+=aBalls[i].iDX;
aBalls[i].iCurY+=aBalls[i].iDY;
  • 当小球碰到墙时将反弹
if((aBalls[i].iCurX<=0+aBalls[i].iRadius)) {aBalls[i].iCurX=aBalls[i].iRadius+1;aBalls[i].iDX=-aBalls[i].iDX;
}
if((aBalls[i].iCurX >=oCanvas.width-aBalls[i].iRadius)) {aBalls[i].iCurX=oCanvas.width-aBalls[i].iRadius-1;aBalls[i].iDX=-aBalls[i].iDX;
}
if(aBalls[i].iCurY<=0+aBalls[i].iRadius) {aBalls[i].iCurY=aBalls[i].iRadius+1;aBalls[i].iDY=-aBalls[i].iDY;
}
if(aBalls[i].iCurY >=oCanvas.height-aBalls[i].iRadius) {aBalls[i].iCurY=oCanvas.height-aBalls[i].iRadius-1;aBalls[i].iDY=-aBalls[i].iDY;
}
  • 引力(加速度)控制

    • 原始位置对小球有吸引力
    • 鼠标对小球具有排斥力
    • 存在与移动方向相反的阻力
 //速度控制
if(oMousePos.x!=""){//有鼠标,存在引力和斥力var Dis=Math.pow(Math.pow(aBalls[i].iCurX-oMousePos.x,2)+Math.pow(aBalls[i].iCurY-oMousePos.y,2),0.5);aBalls[i].iDX+=0.003*(aBalls[i].iOriginX-aBalls[i].iCurX)+20/Math.pow(Dis,1.8)*(aBalls[i].iCurX-oMousePos.x);aBalls[i].iDY+=0.003*(aBalls[i].iOriginY-aBalls[i].iCurY)+20/Math.pow(Dis,1.8)*(aBalls[i].iCurY-oMousePos.y);
}else{//无鼠标,只存在引力aBalls[i].iDX+=0.003*(aBalls[i].iOriginX-aBalls[i].iCurX);aBalls[i].iDY+=0.003*(aBalls[i].iOriginY-aBalls[i].iCurY);
}
//限制最大速度
if(aBalls[i].iDX>MaxSpeed) aBalls[i].iDX=MaxSpeed;
if(aBalls[i].iDX<-MaxSpeed) aBalls[i].iDX=-MaxSpeed;
if(aBalls[i].iDY>MaxSpeed) aBalls[i].iDY=MaxSpeed;
if(aBalls[i].iDY<-MaxSpeed) aBalls[i].iDY=-MaxSpeed;
//阻力
aBalls[i].iDX*=0.98;
aBalls[i].iDY*=0.98;

以上物理控制流程包含在了updateBalls()函数里,而这个函数并不实际进行动画,只是对象属性。

实际上计算公式并没有硬性规定,公式不同自然会有不同的运动效果,大家可以自己研究。


动画控制

动画采用requestAnimationFrame,而没有采用定时器(实测前者的流畅度将远超后者)。关于requestAnimationFrame,网上已经有了很详尽的资料,在此不在赘述。

function draw() {updateBalls();oContext.clearRect(0,0,oCanvas.width,oCanvas.height);oContext.fillText("by QS",800,260);for(var i=aBalls.length-1;i>=0;i--){oContext.beginPath();oContext.arc(aBalls[i].iCurX,aBalls[i].iCurY,aBalls[i].iRadius,0,2*Math.PI);oContext.fillStyle=aBalls[i].sColor;oContext.fill();}requestAnimFrame(draw);
};

注意遍历每个球的时候,首先要beginPath(),否则球将会连接在一起。


以上是这个demo的核心部分。

写的过程中遇到了以下几个问题

撞墙检测

由于位置的变化不是连续的(即dx/dy会大于1),因此总有可能让小球直接穿过墙壁。试了几种算法,都不能很好的解决这个问题,后来读了Google小球的源码,发现他的处理方式是:只要到了区域范围以外,就将位置坐标强制设为临界值(而非在基础上加dx/dy)。这么说可能表述不清楚,看代码就清楚了:

if((aBalls[i].iCurX<=0+aBalls[i].iRadius)) {aBalls[i].iCurX=aBalls[i].iRadius+1;aBalls[i].iDX=-aBalls[i].iDX;
}

阻力

一开始没有考虑到阻力,于是小球最后在原始位置附近徘徊,后来想起高中学的动量守恒,就想起来阻力这回事了。

aBalls[i].iDX*=0.98;
aBalls[i].iDY*=0.98;

转载于:https://www.cnblogs.com/qs20199/p/4452271.html

Canvas实战---模仿GOOGLE浮动小球效果相关推荐

  1. html5刮奖效果,HTML5+Canvas实战之刮奖效果

    项目描述 HTML5+Canvas实战之刮奖效果,实现网页上刮奖,可以用作验证码: 可以在移动设备上和PC端网页(浏览器要支持canvas)上运行 ##使用说明 var lottery = new L ...

  2. 用Xamarin 实现园友的 :Android浮动小球与开机自启动

    原文:用Xamarin 实现园友的 :Android浮动小球与开机自启动 前两天看园子里有筒子写了个 Android浮动小球与开机自启动  , 感觉这种被 360 玩烂的功能原来是如此的简单啊... ...

  3. android 小球效果,Android开发实现跟随手指的小球效果示例

    本文实例讲述了android开发实现跟随手指的小球效果.分享给大家供大家参考,具体如下: 配置drawview类用于绘制小球 public class drawview extends view { ...

  4. 前端实战小案例--canvas实战之FlappyBird小游戏

    前端实战小案例--canvas实战之FlappyBird小游戏 想练习更多前端案例,请进个人主页,点击前端实战案例->传送门 觉得不错的记得点个赞?支持一下我0.0!谢谢了! 不积跬步无以至千里 ...

  5. canvas实战之酷炫背景动画(二)

    系列文章 canvas实战之酷炫背景动画(一) canvas实战之酷炫背景动画(二) canvas实战之酷炫背景动画(三) canvas实战之酷炫背景动画(四) canvas实战之酷炫背景动画(五) ...

  6. 安卓作业----慕课移动应用开发作业15之模仿实现微信界面效果(二)

    此篇综合运用自定义ActionBar.ContextMenu.PopupWindow.Fragment.ViewPager 以及RecyclerView等实现微信页面效果. 同时这也是中国大学慕课移动 ...

  7. html自定义动画让元素下落,jQuery实现的模仿雨滴下落动画效果

    本文实例讲述了jQuery实现的模仿雨滴下落动画效果.分享给大家供大家参考,具体如下: 效果如图: 实现思路:定时器每隔x秒生成宽高.下落速度(即动画执行时间).left随机的div. 1.CSS: ...

  8. 【Android自定义控件】之仿网易星球浮动小球

    仿网易星球浮动小球 读呗开发过程中遇到新需求,类似于网易星球收集黑钻的界面,考虑到可能也有人会使用,索性封装成库,后面好移植使用 先看看需要实现的效果: 需求分析: 数据集合可能是int.double ...

  9. 模仿一个球落地效果,最终停在地面上(仿真效果,CSS实现)

    模仿一个球落地效果,最终停在地面上(仿真效果,CSS实现) 效果图 制作步骤 先准备个球和一个地面 给球准备动效 再给些曲线运动的效果 完整代码 本博客其他文章推荐 效果图 制作步骤 先准备个球和一个 ...

最新文章

  1. centos6.4下LVS+keepalived的高可用(LVS/DR模式)
  2. codeblocks、wxWidgets环境配置
  3. Kylin的cube模型
  4. jq 点击按钮跳转到微信_【看这里】教你用微信小程序登陆全国青少年普法网,方便快捷!...
  5. 《妥协的完美主义—优秀产品经理的实践指南(卷一)》一2.4 分工常见的错误...
  6. C#调用存储过程的通用类
  7. Java IdentityHashMap size()方法与示例
  8. Lrc歌词-开发标准 (转)
  9. Today's Progress
  10. Oracle数据库一致性读的原理
  11. 微信小程序 #项目笔记# | 从0到1实现婚礼邀请函小程序
  12. Elasticsearch 7.13 删除文档后如何释放存储空间、手动执行forcemerge操作
  13. SpringBoot简单实现上传图片到七牛云
  14. Java代码复用的三种常用方式:继承、组合和代理
  15. Non-UTF-8 code starting with ‘\xb5‘ in file D:\eclipse\Python\test\__init__.
  16. 外贸老鸟帮新人点评、修改的5个开发信案例
  17. venue 11 pro 刷linux,普通用户关心的JingOS问题解答,由JingOS开发人员作答
  18. Flash as2.0与3.0功能性能详细对比
  19. springboot项目接入短信
  20. 丢失api-ms-win-crt-runtime-l1-1-0.dll已解决

热门文章

  1. 数独游戏技巧从入门到精通_中国茶艺技巧:500集从入门到精通教程,视频+素材+笔记...
  2. 高效的Java集合框架GNU Trove的使用
  3. Java出现No enclosing instance of type Test is accessible. Must qualify the allocation with an enclosin
  4. pytorch load state dict_学习Pytorch过程遇到的坑(持续更新中)
  5. c语言大学期末考试题及答案,大学C语言期末考试题4及答案
  6. 广西二级c语言试题,广西区计算机等级考二级C语言笔试试题及答案.doc
  7. PHP js 点击按钮 切换模版,javascript点击按钮实现隐藏显示切换效果_javascript技巧...
  8. sinr是什么意思_明明是满格信号,可是却不如两三格,这是什么情况?
  9. 【boost】time.1 同步计数器
  10. oracle初始化序列值,如何修改序列(Sequence)的初始值(START WITH)