github请点这里
一、简介:轮播动画是日常常见的前端动画之一,有许多优秀的轮播库,比如:swiper,基于css3实现的Animate.css,以及bootstrap等,这些动画库提供了种类繁多的动画形式,在实际的项目开发中为了做个别动画而引入,显得多余,为此,本人实现了一个轮播动画函数(类).
二、主要功能:
pc端:
1.自动播放
2.左右切换
3.支持鼠标移入移出动画暂停和播放
移动端:
1.自动播放
2.自由滑动
三、实现过程
阅读前考虑两个问题:
1.当前图片是第一张,用户仍然向右滑动怎么办?
2.当前图片是最后一张,用户向左滑动图片怎么办?
1.自动播放
·考虑到动画的流畅性,播放速度为1000ms/60(取16毫秒切换完成一张图片)
·每张图片自动播放完后等待3秒播放下一张,时间可自由配置
·通过css3动画属性实现图片切换
var timer = setInterval(function() {
that.bar.style.transitionDuration='.3s'//css3动画
that.left=-that.index*that.w
setLeft(that.bar,that.left)
that.index=that.index+1
},3000)
考虑到上面的两个问题,在初始化轮播动画时,复制该组图片(为区别,初始的轮播图片视为第一组,复制的视为第二组),在每次css3动画完成时,监听其完成事件,判断如果播放计数已经超过初始的轮播长度,重置当前的播放计数,并且瞬间移动轮播条到第一组图片的相应位置
that.ele.addEventListener('transitionend',function() {
that.stop()
that.bar.style.transitionDuration=' '
if (that.index>that.len) {
that.index=that.index%that.len?that.index%that.len:1
that.left=-(that.index-1)*that.w
setLeft(that.bar,that.left)
}
that.showNav()
that.move(that)
})
2.左右切换
给轮播动画的可视区域添加向左切换和向右切换的按钮,用户点击向左按钮,可视区域切换成当前图片的前一张图片,点击向右切换按钮,可视区域切换成当前图片的后一张图片,可以选择切换时有动画效果或者瞬间移动.以下采用瞬间移动
functionprevPic(that) {
if (that.index===1) {
that.index=that.len*2
that.left=-that.w*(that.len*2-1)
setLeft(that.bar,that.left)
} else {
that.left=-that.w*(that.index-2)
setLeft(that.bar,that.left)
that.index=that.index-1
}
}
functionnextPic(that) {
if (that.index===that.len*2) {
that.index=1
that.left=0
setLeft(that.bar,that.left)
} else {
that.left=-that.w*that.index
setLeft(that.bar,that.left)
that.index=that.index+1
}
}
3.鼠标移入移出
]添加鼠标移入移出事件
that.ele.addEventListener('mouseover',function(ev) {
that.stop()
if (ev.target.className==='navigation_index') {
var e=ev.target
showPic(e.dataset.index)
that.index=+e.dataset.index
that.showNav()
}
return
})
that.ele.addEventListener('mouseout',function(ev) {
if (ev.target.className==='navigation_index') {
that.showNav()
that.move(that)
}
return
})
移动端区别于pc端在以下几点:
1.移动端有touch事件,pc端没有,此时应该注意touch事件和click事件冲突的处理;
2.移动端有灵敏的touch事件,因此把左右切换按钮隐藏,用户通过touch事件移动图片同样能左右切换图片,自由滑动
that.ele.ontouchstart = function(ev) {
that.bar.style.transitionDuration=''
that.stop()
ev.preventDefault()
startPoint=ev.changedTouches[0].pageX//获得手指触摸屏幕的坐标
startEle=that.bar.offsetLeft//保存当前轮播条的位置
}
that.ele.ontouchmove=function(ev) {
curPoint=ev.changedTouches[0].pageX
distance=curPoint-startPoint;
if (that.index===1&&distance>0) {
that.left = -that.w*that.len+distance
that.bar.style.left=that.left+'px'
} else {
that.left=startEle+distance
that.bar.style.left=that.left+'px'
}
}
that.ele.ontouchend = function (ev) {
for (var i = 0; i < touchTimer.length; i++) {
clearTimer(touchTimer[i], 2);
}
that.bar.style.transitionDuration = '.3s';
if (Math.abs(distance) >= that.w / 3) {
if (distance > 0) {
if (that.index === 1) {
that.index = that.len + 1;
}
prevPic(that);
that.showNav();
} else {
if (that.index === that.len * 2) {
that.index = that.len;
}
nextPic(that);
that.showNav();
}
} else {
if (that.index === 1 && distance > 0) {
that.index = that.len + 1;
}
if (that.index === that.len * 2 && distance < 0) {
that.index = that.len;
}
showPic(that.index);
//如果distance===0,无法触发transitionend事件,通过移动一点点距离来触发
if (Math.abs(distance) === 0) {
that.bar.style.left = that.bar.offsetLeft - 0.1 + 'px';
}
}
distance = 0;
};
总结:仔细看上面的代码,会发现,每个事件在触发前都把当前所有的定时器清除掉,这是为了避免在特定事件发生的时候,定时器动画产生干扰而导致体验不佳,定时器在动画中是一个非常重要的使用,详细了解,请参考我的下一篇文章.