好久没有写过原生JS了,突然没事做,写了一个跟着鼠标走的加载小动画,最终效果如下图:

这个效果实现起来非常简单,大概思路是:先用 CSS3 的 border-radius 属性将三个 div 的样式设置为圆形,然后定义一个椭圆路径,最后用定时器或帧函数使得三个 div 绕着椭圆路径旋转,同时椭圆路径的中点始终跟随者鼠标移动。

有了思路就可以开始写代码了,先把 html 和 css 部分写好:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>跟着鼠标走的加载小动画</title><style>body{padding: 0;margin: 0;}/*初始化body*/#container{width:100%;height:100%;margin: 0;padding: 0;background-color: white;position: absolute;}/*整个网页容器的样式*/#ball_1{border-radius: 100%;position: absolute;width:8px;height:8px;background-color: #999;}/*第一个小球样式*/#ball_2{border-radius: 100%;position: absolute;width:12px;height:12px;background-color: #666;}/*第二个小球样式*/#ball_3{border-radius: 100%;position: absolute;width:16px;height:16px;background-color: #333;}/*第三个小球样式*/</style>
</head>
<body><div id="container"></div> <!--整个网页的容器--></body>
</html>

写好静态页面代码后,开始写 JS 代码:

(一)用 js 的方式生成3个小球

<script>//获得容器对象var container = document.getElementById("container");   //定义小球数组var ball_arr = [];     //生成3个小球for(var i=1; i<=3; i++){var ball = document.createElement('div'); //创建小球divball.id = "ball_" + i;             //设置小球对应的样式ball.style.display = "none";      //暂时不显示小球ball_arr.push( ball );             //压入小球数组container.appendChild( ball );      //添加小球到网页中显示}</script>

(二)定义椭圆路径

//定义椭圆路径
var path_length = 50;  //定义路径的半长轴的长度
var path_width = 30;   //定义路径的半短轴的长度
var path_angel = 0;        //初始化与正半轴所成的角度角度为0(顺时针为正)
var angel_increase = 1.3;  //小球运动角度增量(用于做小球旋转动画动画)
var ball_gap = 0.8;        //小球间距(用于做小球旋转动画)

这里可能会有疑问,怎么定义椭圆路径?怎么在代码方面描述一个椭圆? 一般情况下,我们要用代码画一个图形的路径,就要用到图形对应的参数方程,比如椭圆的参数方程为:

x=acosα
y=bsinα

其中,a为椭圆的半长轴的长度,b为半短轴的长度,α为与正半长轴所成的角度。于是,用 a, b, α 这两个量,就能确定某个构成椭圆路径的点的坐标。如果 a, b 长度不变,不断改变角度 α , 就能确定一个构成椭圆路径的几乎所有点的坐标,有了这些坐标,3个小球就能准确地围着椭圆的路径运动而不会偏离出去。

如果仍然难以理解,可以用一张图作辅助理解,如下图,红点M的轨迹是椭圆,M(x,y) = (|OA|cosa,|OB|sina) = (acosα, bsinα)。

(三)定义鼠标移动事件

由于椭圆路径的中点是跟着鼠标跑,所以我们需要定义鼠标移动事件来更新一对鼠标坐标的变量,在此前,先把一对鼠标坐标变量定义好。

 //定义实时鼠标坐标var mouseX = 0;var mouseY = 0;

由于不同的浏览器,监听鼠标移动事件的方式不一样,所以需要用兼容性写法监听鼠标移动事件。

 //鼠标移动事件(兼容性写法)if (document.addEventListener) { //FireFox,Chrome,Opera…container.addEventListener('mousemove',onMouseMove,false); //事件会在鼠标指针移动时发生。 }else if (document.attachEvent) { //IEcontainer.attachEvent('onmousemove', onMouseMove, false); //事件会在鼠标指针移动时发生。}else { //Other(IE,FireFox,Chrome,Opera等,绝大部分浏览器支持方法 onclick 监听)container.onmousemove = onMouseMove;}

编写鼠标移动事件的回调处理函数,实时更新鼠标坐标变量。

 //鼠标移动事件function onMouseMove(event){//更新坐标mouseX = event.clientX + document.body.scrollLeft - document.body.clientLeft;mouseY = event.clientY + document.body.scrollTop - document.body.clientTop;}

(四)编写小球旋转加载动画

在 js 中编写动画,一般使用帧事件或者定时器,在这里我使用了帧事件函数 requestAnimFrame 方式来编写动画(如果有对 requestAnimFrame 不了解的童鞋,先自行查询)。由于不同浏览器对帧事件的兼容性不相同,所以先要对帧事件函数进行兼容性处理。

 //定义兼容性帧事件window.requestAnimFrame = (function(){return  window.requestAnimationFrame       || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame    || window.oRequestAnimationFrame      || window.msRequestAnimationFrame     || function( callback ){window.setTimeout(callback, 1000 / 60);};})();//兼容性取消帧事件window.cancelAnimationFrame = (function () {return window.cancelAnimationFrame ||window.webkitCancelAnimationFrame ||window.mozCancelAnimationFrame ||window.oCancelAnimationFrame ||function (timer) {window.clearTimeout(timer);};})();

接下来在帧事件中编写小球绕着椭圆路径旋转的动画。

 //监听帧事件,帧渲染和帧绘制的变量var timer = null;//根据椭圆路径,执行小球运动function drawFrame(){for(var i=0; i<ball_arr.length; i++){var ball = ball_arr[i];//显示小球ball.style.display = "block";//转化角度为弧度制var angel = ((path_angel * Math.PI / 180) + (i * ball_gap)) % 360;//更新小球横坐标ball.style.left = path_length * Math.cos(angel) + mouseX - ball.style.width/2 - document.body.clientLeft + "px";//更新小球纵坐标ball.style.top = path_width * Math.sin(angel) + mouseY - ball.style.height/2 - document.body.clientTop + "px";//根据增量更新角度path_angel = (path_angel + angel_increase) % 360;}//再次渲染timer = requestAnimationFrame(drawFrame);}

其中,ball.style.left = path_length * Math.cos(angel); 对应了椭圆的参数方程的 x=acosα。

同理,ball.style.top = path_width * Math.sin(angel);   对应了椭圆的参数方程的 y=bsinα。

(五)最后,调用编写好的动画即可。

timer = requestAnimationFrame(drawFrame);

最后,把以上代码整合起来,完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>跟着鼠标走的加载小动画</title><style>body, #container{padding: 0;margin: 0;}#container{width:100%;height:100%;background-color: white;position: absolute;}#ball_1, #ball_2, #ball_3{border-radius: 100%;position: absolute;}#ball_1{width:8px;height:8px;background-color: #999;}#ball_2{width:12px;height:12px;background-color: #666;}#ball_3{width:16px;height:16px;background-color: #333;}</style>
</head>
<body><div id="container"></div><script>//初始化3个小球var container = document.getElementById("container");var ball_arr = [];for(var i=1; i<=3; i++){var ball = document.createElement('div');ball.id = "ball_" + i;ball.style.display = "none";ball_arr.push( ball );               //压入小球数组container.appendChild( ball );      //添加小球到网页中显示}//定义椭圆路径var path_length = 50; //定义路径的半长轴的长度var path_width = 30;  //定义路径的半短轴的长度var path_angel = 0;       //初始化角度为0var angel_increase = 1.3; //小球运动角度增量var ball_gap = 0.8;      //小球间距//鼠标移动事件(兼容性写法)var webUI = container;if (document.addEventListener) { //FireFox,Chrome,Opera…// webUI.addEventListener('click', onMouseClick, false); //单击事件是在同一元素上发生了鼠标按下事件之后又发生了鼠标放开事件时才发生的。// webUI.addEventListener('mousedown', OnMouseDown, false); //事件会在鼠标按键被按下时发生。// webUI.addEventListener('mouseup', OnMouseUp, false); //事件会在鼠标按键被松开时发生。webUI.addEventListener('mousemove',onMouseMove,false); //事件会在鼠标指针移动时发生。// webUI.addEventListener('mouseover', onMouseOver, false); //事件会在鼠标指针移动到指定的对象上时发生。// webUI.addEventListener('mouseout', onMouseOut, false); //事件会在鼠标指针移出指定的对象时发生。//c.addEventListener('touch',onMouseClick,false);       }else if (document.attachEvent) { //IE// webUI.attachEvent('onclick', onMouseClick, false); //单击事件是在同一元素上发生了鼠标按下事件之后又发生了鼠标放开事件时才发生的。// webUI.attachEvent('onmousedown', OnMouseDown, false); //事件会在鼠标按键被按下时发生。// webUI.attachEvent('onmouseup', OnMouseUp, false); //事件会在鼠标按键被松开时发生。webUI.attachEvent('onmousemove', onMouseMove, false); //事件会在鼠标指针移动时发生。// webUI.attachEvent('onmouseover', onMouseOver, false); //事件会在鼠标指针移动到指定的对象上时发生。// webUI.attachEvent('onmouseout', onMouseOut, false); //事件会在鼠标指针移出指定的对象时发生。}else { //Other(IE,FireFox,Chrome,Opera等,绝大部分浏览器支持方法 onclick 监听)alert("您的当前的浏览器可能是:……");// webUI.οnclick=onMouseClick;// webUI.οnmοusedοwn=OnMouseDown;// webUI.οnmοuseup=OnMouseUp;webUI.οnmοusemοve=onMouseMove;// webUI.οnmοuseοver=onMouseOver;// webUI.οnmοuseοut=onMouseOut;}//定义实时鼠标坐标var mouseX = 0;var mouseY = 0;//鼠标移动事件function onMouseMove(event){//先停止小球运动if( timer != null ){cancelAnimationFrame(timer);}//更新坐标mouseX = event.clientX + document.body.scrollLeft - document.body.clientLeft;mouseY = event.clientY + document.body.scrollTop - document.body.clientTop;//开启小球运动timer = requestAnimationFrame(drawFrame);}//定义帧事件(兼容性写法)window.requestAnimFrame = (function(){return  window.requestAnimationFrame       || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame    || window.oRequestAnimationFrame      || window.msRequestAnimationFrame     || function( callback ){window.setTimeout(callback, 1000 / 60);};})();//取消帧事件(兼容性写法)window.cancelAnimationFrame = (function () {return window.cancelAnimationFrame ||window.webkitCancelAnimationFrame ||window.mozCancelAnimationFrame ||window.oCancelAnimationFrame ||function (timer) {window.clearTimeout(timer);};})();//监听帧事件,帧渲染和帧绘制的变量var timer = null;//根据椭圆路径,执行小球运动function drawFrame(){for(var i=0; i<ball_arr.length; i++){var ball = ball_arr[i];//显示小球ball.style.display = "block";//转化角度为弧度制var angel = ((path_angel * Math.PI / 180) + (i * ball_gap)) % 360;//更新小球横坐标ball.style.left = path_length * Math.cos(angel) + mouseX - ball.style.width/2 - document.body.clientLeft + "px";//更新小球纵坐标ball.style.top = path_width * Math.sin(angel) + mouseY - ball.style.height/2 - document.body.clientTop + "px";//根据增量更新角度path_angel = (path_angel + angel_increase) % 360;}//再次渲染timer = requestAnimationFrame(drawFrame);}</script></body>
</html>

【JavaScript】实现三个小球围着椭圆旋转的加载动画相关推荐

  1. android酷炫转圈动画,android常用旋转线条加载动画

    想要知道关于更多自定义View的实例,请参考:android自定义View索引 先上个效果图,以免大家跑错地了. 嗯,整个来说呢,除了舍不得充VIP去掉水印之外,其他都挺好的. 下面开始实现我们的效果 ...

  2. ios新手开发——toast提示和旋转图片加载框

    不知不觉自学ios已经四个月了,从OC语法到app开发,过程虽然枯燥无味,但是结果还是挺有成就感的,在此分享我的ios开发之路中的小小心得~废话不多说,先上我们今天要实现的效果图: 有过一点做APP经 ...

  3. php带旋转动画刷新页面,CSS_CSS实现弹簧效果的旋转加载动画,先看看效果,像是弹簧在伸缩 - phpStudy...

    CSS实现弹簧效果的旋转加载动画 先看看效果,像是弹簧在伸缩: 具体代码: 此处用到CSS3的transform属性. CSS3的变形(transform)属性让元素在一个坐标系统中变形.这个属性包含 ...

  4. CSS 实现加载动画之四-圆点旋转

    原文:CSS 实现加载动画之四-圆点旋转 圆点旋转也是加载动画中经常用到的.其实现方式和菊花旋转一样,只不过一个是线条形式,一个是圆点形式.圆点按照固定的旋转角度排列,加上延时的改变透明度的动画就可以 ...

  5. 用css3制作旋转加载动画的几种方法

    2019独角兽企业重金招聘Python工程师标准>>> 以WebKit为核心的浏览器,例如Safari和Chrome,对HTML5有着很好的支持,在移动平台中这两个浏览器对应的就是i ...

  6. CSS 实现加载动画之五-光盘旋转

    今天做的这个动画叫光盘旋转,名字自己取的.动画的效果估计很多人都很熟悉,就是微信朋友圈里的加载动画.做过前面几个动画,发现其实都一个原理,就是如何将动画的元素如何分离出来.这个动画的实现也很简单,关键 ...

  7. html实现图片加载动画效果,HTML5+javascript实现图片加载进度动画效果

    在网上找资料的时候,看到网上有图片加载进度的效果,手痒就自己也写了一个. 图片加载完后,隐藏loading效果. 想看加载效果,请ctrel+F5强制刷新或者清理缓存. 效果预览: 0% 代码如下: ...

  8. CSS 实现加载动画之一-菊花旋转

    CSS 实现加载动画之一-菊花旋转 原文:CSS 实现加载动画之一-菊花旋转 最近打算整理几个动画样式,最常见的就是我们用到的加载动画.加载动画的效果处理的好,会给页面带来画龙点睛的作用,而使用户愿意 ...

  9. css光盘转动,CSS 实现加载动画之五-光盘旋转

    CSS 实现加载动画之五-光盘旋转 今天做的这个动画叫光盘旋转,名字自己取的.动画的效果估计很多人都很熟悉,就是微信朋友圈里的加载动画.做过前面几个动画,发现其实都一个原理,就是如何将动画的元素如何分 ...

最新文章

  1. Python+Requests+Pytest+YAML+Allure实现接口自动化
  2. css3动画 --- Transition
  3. Java基础与数据库对应数据--Java基础2阶段
  4. 7年,OpenStack从入门到放弃
  5. 第十七章 模型压缩及移动端部署
  6. iOS网络开发—POST请求和GET请求
  7. c++ stl下的sort()函数介绍及基本用法
  8. [HP NX6320] 安装 windows2003 操作系统 全过程
  9. VMware虚拟机启动失败:“DevicePowerOn”
  10. 高中数学立体几何知识点总结(八大定理)
  11. 机械革命电脑MyApp安装包
  12. 古筝四秀 宋婷婷、付娜、常静、吴莉
  13. vb.net 实现图片圆形渐变模糊
  14. 【滴水逆向笔记】C语言指针
  15. ubuntu16.04根目录磁盘空间扩容及可能遇到的问题(亲测有效)
  16. 解决element-UI中分页组件显示英文
  17. 解决java.lang.UnsatisfiedLinkError
  18. Spring Boot——容器相关配置
  19. Url被多次转义 URLDecoder.decode(url,“UTF-8“)
  20. 《Armv8/armv9架构入门指南》-【第十九章】ARMv8模型

热门文章

  1. 核心岗位流失怎么办?
  2. java 下载文件模板
  3. 散热性能测试软件,三款机箱散热性能测试
  4. 208 68使用计算机,SMT工艺试卷
  5. macOS中快速复制文件路径
  6. html中设置content-disposition,Content-Disposition
  7. 2020年美团技术团队最受欢迎的16篇技术文章
  8. 打造高质效的技术团队 —— 酝酿篇
  9. WebService详细教程
  10. 分享好用无广告的手机浏览器,亲测值得下载