在我们进行web页面开发的过程中,如何与用户进行友好、有趣的交互,是我们必须考虑的问题。
比如:导航条中滑动的动画特效、点击加入购物车按钮通过抛物线加入右侧购物车的动画特效,当然还有一些网页游戏的开发:微信打飞机、打砖块等。 那么我们要实现这些好玩又有趣的动画,就需要我们对动画的基础【运动】炉火纯青,那么这个部分的学习,我们会对运动展开学习,并且通过大量的实例来帮助大家完成这个阶段的学习。
Js运动,本质来说,就是让web 上DOM 元素动起来。而想要DOM 动起来,改变其自身的位置属性,比如高宽,左边距,上边距,透明度等。动画的原理就是把不同状态的物体,串成连续的样子,就像一本书,画了几个小人,然后一翻书,就看见小人在动。js动画也一样。不同状态的DOM,用定时器控制,就能得到动画效果。
那么我们首先来看一下如何实现运动
方法:
1.运动的物体使用绝对定位
2.通过改变定位物体的属性(left、right、top、bottom)值来使物体移动。例如向右或左移动可以使用offsetLeft(offsetRight)来控制左右移动。
步骤:
1、开始运动前,先清除已有定时器 (因为:是连续点击按钮,物体会运动越来越快,造成运动混乱)
2、开启定时器,计算速度
3、把运动和停止隔开(if/else),判断停止条件,执行运动
在javascritp中,有两个关于定时器的专用函数,它们是:
1.倒计定时器:timer=setTimeout(函数名,time);
2.循环定时器:timer=setInterval(函数名,time);
function()是定时器触发时要执行的是事件的函数,可以是一个函数,也可以是几个函数,或者javascript的语句也可以,但要用;隔开;delaytime则是间隔的时间,以毫秒为单位。
倒计时定时器就是在指定时间后触发事件,而循环定时器就是在间隔时间到来时反复触发事件,其区别在于:前者只是作用一次,而后者则不停地作用。
倒计时定时器一般用于页面上只需要触发一次的的情况,比如点击某按钮后页面在一定时间后跳转到相应的站点,也可以用于判断一个浏览者是不是你的站点上的“老客”,如果不是,你就可以在5秒或者10秒后跳转到相应的站点,然后告诉他以后再来可以在某个地方按某一个按钮就可以快速进入。
循环定时器一般用于站点上需要从复执行的效果,比如一个javascript的滚动条或者状态栏,也可以用于将页面的背景用飞雪的图片来表示。这些事件需要隔一段时间运行一次。
有时候我们也想去掉一些加上的定时器,此时可以用clearTimeout(timename) 来关闭倒计时定时器,而用clearInterval(timename)来关闭循环定时器。
1.运动:匀速运动(让物体动起来)
对定时器的使用
给DIV加绝对定位
offsetLeft
➤问题:到达某个特定位罝停止
解决:做判断,符合条件时关掉定时器(存定时器timer)
速度变慢(一般不动时间,而是改数字-速度)
用变量存速度
➤问题:取7时,offsetLeft没有等于300的时候,div停不下来
解决:>=300 //停在301
➤问题:到300后点击按钮还继续走
原因:点击按钮,执行函数,开定时器(执行当前函数一至少执行一次)
解决:加else (没有到达目标之前才执行)
➤问题:连续点击,速度变快
原因:每点击一次就开一个定时器,点击几次就有几个定时器同时工作
解决:保证每次只有一个定时器工作,先cearlnterval ()
示例1(分享菜单/鼠标移入划出,鼠标移出划入)▼
示例2(淡入淡出效果/鼠标移入淡出,鼠标移出淡入)▼
示例3 匀速运动的停止条件(距离足够近)示例代码▼
2、变速运动
逐渐变慢,最后停止
距离越远速度越大
速度有距离决定
速度=(目标值-当前值)/缩放系数
如果没有【缩放系数】速度太大,瞬间到达终点.没有过程
➤问题:并没有真正到达300
原因:速度只剩0.9 像素是屏幕能够显示的最小单位,并不会四舍五入掉
Math.ceil ()向上取整
Math.floor ()向下取整
➤问题:向左走,又差一块--Math.floor ()
判断:三目speed=speed>0 ? Math.ceil ( speed ): Math.floor ( speed )
示例代码▼
3、多物体运动
多个div ,鼠标移入变宽
运动框架传参obj,知道让哪个物体动起来
用到缓冲一定要取整
➤问题:div没运动回去 //清除前一个定时器
原因:只有一个定时器
解决:加物体上的定时器,使每个物体都有一个定时器。定时器作为物体属性
多个div淡入淡出
首先关闭物体上的定时器
经验:多物体运动框架所有东西都不能共用
➤问题:不是因为定时器,而是因为alpha
解决:作为属性附加到物体上/不以变量形式存在
➤问题:offset 的bug 加border变宽
原因:offsetWith并不是真正的width ,它获取的是盒模型尺寸
解决:躲着宽度扔到行间,parselnt ( oDiv.style.width )
进一步解决:getStyle ( obj, name ) currentStyle , getComputedStyle
加border ,只要offset就有问题 去掉offset
示例:多物体运动框架▼
4.任意值运动
任意值运动的单位分为透明度和px。px单位的任意值▼
5.链式运动
多出来的一个参数,只有传进去的时候才调用
鼠标移入变宽,结束之后弹出abc
先横向展开.再以向展开
鼠标移出,先变回不透明,变矮,变窄
基于以上的分析与总结,封装运动框架startMove.js如下:
1,完成如下效果:
▼
2,完成如下效果:
▼
微信打飞机效果图
▼
打砖块效果图
▼