使用原生js实现简单动画效果

我们知道,借助jQuery提供的animate方法,我们可以很容易实现一些常见的js动画效果。而对于颜色等无法用数值直接表示的样式,我们可以通过引入一些jQuery插件来实现。但是随着前端组件化开发的流行,jQuery大量的DOM操作已显得十分多余,正在逐渐从前端技术栈中被淘汰。那么如何使用原生js来实现类似于jQuery中的动画效果呢?下面我们将使用原生js实现一个简单的让div匀速加宽的动画效果。

目标效果

点击按钮使div从100像素加宽为200像素。初始HTML代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>简单js动画的实现</title><style>#nav{margin-top: 20px;width: 100px;height: 100px;background-color: #409eff;}</style>
</head>
<body>
<button onclick="run()">加宽</button>
<div id="nav"></div>
</body>
<script>//需要应用动画效果的目标元素var elem = document.getElementById('nav');//动画配置,为了方便,这里只针对width属性,duration表示动画持续时间var options = {width: '200px',duration: 1000};//启动动画function run(){animate.call(elem, options);}//动画逻辑function animate(options){//动画的具体实现,后面的所有代码均位于该函数内...}
</script>
<html>

初始效果如下:

基本原理

使用js实现动画效果的基本原理是,用window.setInterval(logic, time)控制动画的整体运行过程。logic用于计算和设置当前帧的样式,time给定动画刷新速率(即每隔该间隔就重新计算样式,暂不考虑任务阻塞)。

那么logic如何计算当前帧中div的宽度值呢?首先我们需要获取div的原始宽度和结束宽度,然后根据当前动画执行的百分比,计算当前宽度值,这需要借助三个时间参数来确定。一个是动画的开始时间,我们通过一个简单的函数,来获取当前时间的毫秒数形式,代码如下:

//定时器
var timer = null;
//div的初始宽度和结束宽度
var startWidth = parseInt(window.getComputedStyle(elem)['width']);
var endWidth = parseInt(options.width);function createTime(){//返回当前日期距1970年1月1日午夜(GMT 时间)之间的毫秒数,一种简化写法return (+new Date);
}
var startTime = createTime();

另一个是动画持续时间duration,我们从配置的参数中得到。第三个就是当前时间,我们在logic函数中动态获取。根据这三个参数,我们可以在logic中计算出当前动画的剩余时间:

function logic(){//开始时间 + 持续时间 - 当前时间,结果即为动画的剩余时间,当剩余时间小于0则置0,表示动画结束var remaining = Math.max(0, startTime + options.duration - createTime());

根据动画的剩余时间和动画的持续时间,我们可以很容易计算出当前动画执行的百分比,即:

 //remaining/duration即为动画剩余的百分比,用1去减,得到已执行的百分比var percent = 1 - (remaining / options.duration);

根据动画已执行的百分比,我们就可以计算当前帧元素的样式:

 //(结束宽度 - 开始宽度)* 百分比 + 开始宽度,即为当前帧div的实际宽度var nowWidth = ( endWidth - startWidth ) * percent + startWidth;

然后我们定义一个函数setStyle来为div设置宽度:

 function setStyle(nowWidth){elem.style['width'] = nowWidth + 'px';}

我们通过percent来判断当前动画是否结束,如果结束,就设置样式并且清除定时器,否则只设置样式即可:

 if(percent === 1){setStyle(nowWidth);clearInterval(timer);timer = null;} else {setStyle(nowWidth);}
}

最后,我们在logic函数外启动定时器,设置帧刷新速率为13毫秒(jQuery的默认刷新速率):

timer = setInterval(logic, 13);

总结

完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>简单js动画的实现</title><style>#nav{margin-top: 20px;width: 100px;height: 100px;background-color: #409eff;}</style>
</head>
<body>
<button onclick="run()">加宽</button>
<div id="nav"></div>
</body>
<script>
//需要应用动画效果的目标元素
var elem = document.getElementById('nav');
//动画配置,为了方便,这里只针对width属性,duration表示动画持续时间
var options = {width: '200px',duration: 1000
};
//点击按钮启动动画
function run(){animate.call(elem, options);
}
//动画逻辑
function animate(options){//定时器var timer = null;//div的初始宽度和结束宽度var startWidth = parseInt(window.getComputedStyle(elem)['width']);var endWidth = parseInt(options.width);function createTime(){//返回当前日期距1970年1月1日午夜(GMT 时间)之间的毫秒数,一种简化写法return (+new Date);}var startTime = createTime();function logic(){//开始时间 + 持续时间 - 当前时间,结果即为动画的剩余时间,当剩余时间小于0则置0,表示动画结束var remaining = Math.max(0, startTime + options.duration - createTime());//remaining/duration即为动画剩余的百分比,用1去减,得到已执行的百分比var percent = 1 - (remaining / options.duration); //(结束宽度 - 开始宽度)* 百分比 + 开始宽度,即为当前帧div的实际宽度var nowWidth = ( endWidth - startWidth ) * percent + startWidth;function setStyle(nowWidth){elem.style['width'] = nowWidth + 'px';}if(percent === 1){setStyle(nowWidth);clearInterval(timer);timer = null;} else {setStyle(nowWidth);}}timer = setInterval(logic, 13);
}
</script>
<html>

本示例只简单地实现元素宽度的变化,但是可以从中了解到js动画执行的基本原理。即通过setInterval(logic, time)控制动画执行,logic用于计算每帧的样式,time则为帧刷新速率,这样连续计算和设置元素样式,即形成了动画效果。

使用原生js实现简单动画效果相关推荐

  1. 原生JS实现简单放大镜效果

    [前言] 本文介绍下原生JS实现简单图片放大镜效果 [主体] 时间问题,直接上源码 <!DOCTYPE html> <html> <head><meta ch ...

  2. react中react-custom-scrollbars返回顶部功能,如何使其有平滑动画效果;原生js scroll平滑动画效果

    1.Scrollbars是react-custom-scrollbars插件暴露出来的组件 scrollRef.current.view.scroll({top: 0,left: 0,behavior ...

  3. 原生js判断css动画结束 css 动画结束的回调函数

    原文:原生js判断css动画结束 css 动画结束的回调函数 css3 的时代,css3--动画 一切皆有可能: 传统的js 可以通过回调函数判断动画是否结束:即使是采用CSS技术生成动画效果,Jav ...

  4. css画钟表_利用css+原生js制作简单的钟表

    利用css+原生js制作简单的钟表.效果如下所示 实现该效果,分三大块:html.javascript.css html部分html部分比较简单,定义一个clock的div,内部有原点.时分秒针.日期 ...

  5. 使用JS代码编写动画效果

    使用JS代码编写动画效果 下面展示一些 JS代码. 创建一个可以简单移动的动画函数//obj 要执行动画的对象// attr 想要变化的方向或大小 如width top left//target 目标 ...

  6. 用原生js实现刮奖效果

    用原生js实现简单的刮奖效果 效果图 分析:这是运用canvas来做的,页面结构为一个canvas和一张图片.canvas在最上层,图片在最下层.canvas与图片宽高一致.首先在canvas上填充灰 ...

  7. java喷泉编码_好程序员Java教程分享使用JS实现简单喷泉效果

    原标题:好程序员Java教程分享使用JS实现简单喷泉效果 好程序员Java教程分享使用JS实现简单喷泉效果,最近,在教学生使用JS的基本操作,为了练习JS的基本作用,特地写了一个喷泉效果,代码如下: ...

  8. html5 原生拖拽,原生JS实现拖拽效果

    这篇文章主要为大家详细介绍了原生JS实现拖拽效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了JS实现拖拽效果的具体代码,供大家参考,具体内容如下 ...

  9. java喷泉编码_Java干货分享使用JS实现简单喷泉效果

    Java干货分享使用JS实现简单喷泉效果,最近,在教学生使用JS的基本操作,为了练习JS的基本作用,特地写了一个喷泉效果,代码如下: 页面代码: body{ margin: 0px; } Partic ...

  10. android app启动图片 加动画效果,Android Studio开发APP启动程序时开屏简单动画效果快速有效解决方案...

    Android Studio开发APP启动程序时开屏简单动画效果快速有效解决方案 大家在设计APP的末期,都会想给APP搞一些"花里胡哨"的特效来提高APP的B格.博主表示亲测有效 ...

最新文章

  1. C语言十六进制转八进制(附完整源码)
  2. Git 提交规范-Java程序员收藏必备
  3. python掷骰子期望_python_掷骰子游戏
  4. 作者:顾佳峰(1975-),男,博士,北京大学中国社会科学调查中心研究发展部主任,北京大学创新研究院副院长。...
  5. 行列式的本质是什么?(附MATLAB代码)
  6. 剑指Offer:打印从1到最大的n位数
  7. SAMBA用户访问指定的目录
  8. JavaScript 中的 this 与闭包详解
  9. 关于SQL语言的优化(Oracle)
  10. declare sql语句_SQL高级知识——动态SQL
  11. 思科6000系列交换机配置维护手册
  12. 整体二分算法完整总结
  13. 用JavaScript+HTML实现双色球随机摇号效果
  14. HDU2594 Simpsons’ Hidden Talents 前缀与后缀转化成用s1去匹配s2
  15. 34套Java项目教程+源码包含Java swing项目 Java web项目 Java控制台项目(视频教程+源码)
  16. web数据可视化(ECharts版)
  17. 直播带货系统开发,如何实现一个简单的直播平台
  18. 07深圳浩项隔音窗,隔音知识与方法
  19. Eclipse中更改tomcat版本
  20. SpringCloud(3)——SpringDataJpa之EntityManager的CRUD

热门文章

  1. JDK的安装 - JDK8(1.8.0_301)
  2. python手机版做小游戏代码大全-12岁的少年教你用Python做小游戏
  3. 使用Excel功能抓取网页表格数据
  4. java分页的方法_java实现的分页方法(上一页下一页)
  5. 云桌面优缺点_云桌面真的是办公最佳选择吗?云桌面的优缺点对比
  6. gis怎么提取水系_ArcGIS提取水系并进行生态敏感性分析
  7. IOUtils使用介绍
  8. 【Windows优秀软件推荐】:唧唧down——视频和弹幕全清晰度下载
  9. Android手机开发课程设计之音乐播放器
  10. Phantomjs 生成多页PDF