如何用js自己实现Animate运动函数
js运动是我们学习js必不可少的研究部分,首先我们要知道js的运动其实仅仅是不断改变元素的某个属性值而已,比如不断改变一个绝对定位div的left值,那么你看到的效果就是这个div不断的向右边运动,那么运动的原理就是这样。
我们知道从a这一点到b这一点我们的运动方式有很多,
1.比如匀速运动到这一点
2.比如先快后慢,
3.必须先慢后快等等
所以我们的运动算法也有很多,那么下面我就图解一下如何写我们自己的运动算法
先看匀速算法
于是我们可以用js写出这段代码
/** 运动算法 * t:动画已经消耗的时间 * b:小球初始位置 * c:小球的需要移动额距离 * 动画持续的总时间 * */ var tween = { linear: function(t, b, c, d){ return c * t / d + b; } }
然后我们看看非匀速运动
我们用代码写出来
1 2 3 4 5 | var tween = { strongEaseOut: function ( t, b, c, d){ return t * t *c / (d *d) + b; }, } |
我们现在只是介绍两种不同的运动算法,当然运动算法还要很多,我们不意义例举,我们接着看如何写改变属性的js
首先我们定义一个运动类
1 2 3 4 5 6 7 8 9 | var Animate = function ( dom ) { this .dom = dom; this .startTime = 0; this .startPos = 0; this .endPos = 0; this .propertyName = null ; this .easing = null ; this .duration = null ; } |
主要是初始化一些数据,然后我们在Animate的原型上定义一个start方法,该方法表示运动开始
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Animate.prototype.start = function ( propertyName,endPos,duration,easing ){ this .startTime = + new Date; //记录现在的开始时间 this .startPos = this .dom.getBoundingClientRect()[ propertyName ]; //记录开始的位置 this .propertyName = propertyName; //需要改变的属性(传) this .endPos = endPos; //得到目标位置(传) this .duration = duration; //得到需要的时间(传) this .easing = tween[ easing ] //选择哪种运动的算法(传) var self = this ; var timeId = setInterval( function (){ //如果self返回false,则取消定时器 if ( self.step()=== false ) { clearInterval( timeId ) } },19) } |
上面的setInterval每隔19毫秒就会执行一次,每次都是执行step方法,step方法就是每次需要计算更新小球的位置
1 2 3 4 5 6 7 8 9 10 11 12 13 | Animate.prototype.step = function (){ //目前的时间 var t = + new Date; //如果时间超过开始时间和需要时间之和,则矫正目前的位置为目标位置 if ( t >= this .startTime + this .duration ) { this .update( this .endPos ) return false ; //返回false为了取消定时器 } //计算小球的位置 var pos = this .easing( t - this .startTime, this .startPos, this .endPos- this .startPos , this .duration) //更新div的属性 this .update( pos ) } |
那么update方法也仅仅就是更新div的属性而已
1 2 3 4 | //更新当前位置 Animate.prototype.update = function ( pos ){ this .dom.style[ this .propertyName ] = pos + 'px' } |
接下来我们看看我们在html里面如何执行,html代码
1 | < div style="position: absolute;background: blue;width: 100px;height: 100px;left: 0;" id="div"></ div > |
然后是执行代码
1 2 3 | var div = document.getElementById( 'div' ) var animate = new Animate( div ) animate.start( 'left' ,500,5000, 'linear' ) |
到现在我们整个运动就结束了
完整的代码地址在我的github上https://github.com/jiangzhenfei/Animate/blob/master/index.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构