这篇博客剖析一个问题,就是怎么实现将元素指定时间运动到目标位置?前面的博客都是在处理运动行为,没有对运动时间做任何限定,只是因为清晰的分析运动行为和实现原理,要想一个动画函数具备健全的功能,并且可以随意使用,通过参数设定动画执行时间是非常有必要的一个设计。

在前面任意一种运动函数内,实质上只有一个变量,这个变量就是运动距离(缓冲运动中添加了因数),当运动距离变大时,运动时间就会变长,动画停止条件是由坐标来决定的。当指定运动时间时,运动速度就会同时受到运动距离和运动时间的限制,动画停止条件也是由时间来控制。

定时定点运动示例代码:

 //css
div{
width:100px;
height:100px;
background:red;
position: absolute;
left: 0px;
opacity:;
}
#top{
top: 100px;
}
#bottom{
top: 300px;
}
//html
<div id="top"></div>
<div id="bottom"></div>
//js
var oDivArray = document.getElementsByTagName('div');
var timer = null;
var targetObj = {
width:400,
height:400,
opacity:50,
left:300,
top:200
}
oDivArray[0].onclick = function(){
startMove(this,targetObj,3000,function(){
startMove(oDivArray[1],targetObj,3000);
});
}
function getStyle(obj,attr){
if(window.getComputedStyle){
return window.getComputedStyle(obj,false)[attr];
}else{
return obj.currentStyle[attr];
}
}
//运动方法startMove的参数:
//obj:运动物体;
//json:目标位置,最终样式值(键值对的形式合成的目标位置对象)
//speed:运动时间(指定运动的时间)
//callback:回调函数
function startMove(obj,json,speed,callback){
//初始位置,移动距离,当前位置
var initialPlace = {};
//新的位置(每次运动的目标点)
var nowPlace;
//结束之前的定时器
clearInterval(obj.timer);
//获取当前时间戳
var createTime = function(){
return (+new Date);
}
//动画开始的时间戳
var startTime = createTime();
//初始位置对象
for(var attr in json){
if(attr == 'opacity'){
initialPlace[attr] = Math.round(parseFloat(getStyle(obj,attr))*100);
}else{
initialPlace[attr] = parseInt(getStyle(obj,attr));
}
}
//定时器
obj.timer = setInterval(function(){
//每次变化的时间
//剩余时间 = Math.max(0,运动开始的时间 + 运动执行事件 - 当前时间) -- 当剩余时间为负数时,返回0
var remaining = Math.max(0, startTime + speed - createTime());
//剩余时间比 = 剩余时间 / 运动时间
var temp = remaining / speed || 0;
//当前时间比 = 1 - 剩余时间比 -- 即执行到某处时间节点
var percent = 1 - temp;
//循环运动到时间节点位置
for(var attr in json){
nowPlace = (json[attr] - initialPlace[attr]) * percent + initialPlace[attr];
if(attr == 'opacity'){
obj.style.opacity = nowPlace / 100;
}else{
obj.style[attr] = nowPlace + 'px';
}
}
//当前时间与运动时间比为1:1时,说明到达运动终点了,结束定时器,并判断是否有回调函数
if(percent == 1){
clearInterval(obj.timer);
typeof callback == 'function' ? callback() : '';
}
},30);
}

示例还是基于链式运动的示例进行修改过来了,但是运动函数已经发生了质的变化。因为代码我都有些注释,就不详细解析了。提一个相对比较重要的点,这篇博客相对于前面的博客(运动系列),这篇博客的动画行为主要是受限定的运动时间来控制的,单次运动距离由运动实际运动时间比总(参数设置的时间)运动时间,来决定一次运动距离。通过时间比的方式来控制运动速度,和决定什么时候停止动画。

然后还有一个参数easing没有实现,如果没有这个参数,运动行为就都是匀速执行了,请看下面的改进方式:

 //在js全局定义运动行为对象
var easingObj = {
linear: function( p ) {
return p;
},
swing: function( p ) {
return 0.5 - Math.cos( p*Math.PI ) / 2;
},
background:function(k) {
if (k < (1 / 2.75)) {
return 7.5625 * k * k;
} else if (k < (2 / 2.75)) {
return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
} else if (k < (2.5 / 2.75)) {
return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
} else {
return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
}
}
}
//然后在startMove运动方法的形参上添加参数easing;参数位置:第四个参数(索引3)
//然后设置默认运动行为或接收设置的运动行为
//对象行为 -- 默认:swing(匀速)
if(!easing){
easing = easingObj.swing;
}else{
easing = easingObj[easing];
}
//将运动节点位置那行代码修改
//实质是将percend用行为函数包裹起来
nowPlace = (json[attr] - initialPlace[attr]) * easing(percent) + initialPlace[attr];

最后调用代码:

oDivArray[0].onclick = function(){
startMove(this,targetObj,3000,"",function(){
startMove(oDivArray[1],targetObj,3000,"background");
});
}

这个方法就完全模仿了jQuery的动画函数animate(),后期我会将这个方法封装,并且会提供缓动函数(easings库)插件接口,缓动函数库手册地址:https://easings.net/zh-cn。运动行为库相对来说还是有些局限性的,所以接下来我会在前面的示例基础上手写弹力效果和撞击效果。一步一步来吧。

相关技术博客参考:

原生JavaScript运动功能系列(五):定时定点运动的更多相关文章

  1. 原生JavaScript运动功能系列(四):多物体多值链式运动

    原生JavaScript运动功能系列(一):运动功能剖析与匀速运动实现 原生JavaScript运动功能系列(二):缓冲运动 原生JavaScript运动功能系列(三):多物体多值运动 多物体多值链式 ...

  2. 原生JavaScript运动功能系列(二):缓冲运动

    匀速运动实现回顾 缓冲运动剖析 示例实现 方法提取 匀速运动实现回顾及缓冲运动剖析: 在这个系列的上一篇博客中原生JavaScript运动功能系列(一):运动功能剖析与匀速运动实现就运动的核心功能组成 ...

  3. 原生JavaScript运动功能系列(一):运动功能剖析与匀速运动实现

    在我们日常生活中运动就是必不可少的部分,走路.跑步.打篮球等.在网页交互设计上运动也是必不可少的部分,创建的网站交互设计运动模块有轮播图,下拉菜单,还有各种炫酷的游戏效果都跟运动密切相关.所以很重要, ...

  4. 原生JavaScript运动功能系列(三):多物体多值运动

    多物体同时出发运动函数实现 多属性同步运动变化实现 一.多物同时触发运动函数实现 前面两个动画示例基本理解了动画的核心:位置变化和速度变化,操作的核心就是定时器分段叠加属性值.但是动画还是基于单个元素 ...

  5. javascript学习-原生javascript的小特效(多个运动效果整理)

    以下代码就不详细解析了,在我之前的多个运动效果中已经解析好多次了,重复的地方这里就不说明了,有兴趣的童鞋可以去看看之前的文章<原生javascript的小特效> <!DOCTYPE ...

  6. javascript学习-原生javascript的小特效(简单的运动效果)

    前些日子看了个视频所以就模仿它的技术来为大家做出几个简单的JS小特效 一:运动特效(主要是通过改变元素的left,right,height,width,opacity来达到运动的效果) 我们今天做一个 ...

  7. javascript学习-原生javascript的小特效(多物体运动效果)

    前些日子看了个视频所以就模仿它的技术来为大家做出几个简单的JS小特效 今天为大家做的是多个物体的运动效果, 1:HTML <body> <ul>       <li> ...

  8. javascript类继承系列五(其他方式继承)

    除了前面学习的三种继承外,还有另外三种:原型继承寄生继承,寄生组合继承都是以: function object(o) { function F() { } F.prototype = o; retur ...

  9. 原生javascript写自己的运动库(匀速运动篇)

    网上有很多JavaScript的运动库,这里和大家分享一下用原生JavaScript一步一步写一个运动函数的过程,如读者有更好的建议欢迎联系作者帮助优化完善代码.这个运动函数完成后,就可以用这个运动函 ...

随机推荐

  1. Codeforces519 E. A and B and Lecture Rooms

    传送门:>Here< 题意:询问给出一棵无根树上任意两点$a,b$,求关于所有点$i$,$dist(a,i) = dist(b,i)$的点的数量.要求每一次询问在$O(log n)$的时间 ...

  2. Peaceful Commission HDU - 1814(输出最小的一组解)

    Description 根据宪法,Byteland民主共和国的公众和平委员会应该在国会中通过立法程序来创立. 不幸的是,由于某些党派代表之间的不和睦而使得这件事存在障碍. 此委员会必须满足下列条件: ...

  3. Java实现月份递减

    问题:从当前月份开始,往前3年的所有月份 返回map类型,key是String,value是Date,map倒序排列 public static Map<String, Date> get ...

  4. 利用纯粹的CSS3替代小图标---向右箭头

    1.向右的箭头>  . 看到很多网站里面向右的箭头都是图片代替的,但是为了网站的性能,我们一般的原则是能够避免使用图片的尽量不用图片   比如看下携程个人中心首页面,向右的箭头 其实现思路是这样 ...

  5. 不是说记住rm -rf的教训就够了

    不是说记住rm -rf的教训就够了 李阿玲· 12 天前 2013年,我在同步CTAN镜像的时候,在/home下我的文件夹里面操作了下面的命令: rsync -av --delete rsync:// ...

  6. luogu3119/bzoj3887 草鉴定 (tarjan缩点+spfa)

    首先缩一波点,就变成了一个DAG,边权是出点的大小 那我们走到某个点的时候可能会有两种状态:已经走过反边或者没走过 于是就把一个点拆成两层(x和x+N),第二层的点表示我已经走过反边了,每层中的边和原 ...

  7. DNA Evolution CodeForces - 828E(树状数组)

    题中有两种操作,第一种把某个位置的字母修改,第二种操作查询与[L, R]内与给出字符串循环起来以后对应位置的字母相同的个数.给出的字符串最大长度是10. 用一个四维树状数组表示 cnt[ATCG的编号 ...

  8. kafka清理数据日志

    背景问题: 使用kafka的路上踩过不少坑,其中一个就是在测试环境使用kafka一阵子以后,发现其日志目录变的很大,占了磁盘很大空间,定位到指定目录下发现其中一个系统自动创建的 topic,__con ...

  9. poj 3186 Treats for the Cows(dp)

    Description FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for gi ...

  10. wildfly 10上使用最新的 Hibernate ORM OGM

    ORM是关系型数据库连接:ogm是No sql数据库连接,Mongo, redis等. 1,下载ogm zip包,解压到wildfly_home\modules\system\layers\base, ...