自定义jQuery插件实现三种动画效果
效果图
思路:
- 先创建页面元素,① 将图片分别放入到创建的a链接中。并将a集合加入至页面中。为每个a设置不同的
zIndex
。② 创建三种不同碎片集合,分别对应从左到右、从上到下、大爆炸动画。在创建碎片集合时除了设置其高、宽、位置,还要设置每个碎片中的background-size
和background-position
。将三种不同碎片集合push
进一个数组中,供后续动画切换使用。- 调用默认动画:遍历
a
集合,找出zIndex
值最大的索引,并通过该索引调用下一张照片对应的动画函数。在该动画函数中,设置页面碎片元素(用找出的索引值求得当前所需要的碎片集合以及当前需要展示的图片)。设置完碎片元素后,根据不同延迟时间将碎片显示出来(动画形式使得每个碎片的opacity
变为1)。在所有碎片显示出来后重新设置a
集合中所有元素的zIndex
值,在设置zIndex
值时,与a
集合长度-1相等的元素淡入,其他元素都淡出。在设置完所有元素的zIndex
值后再次调用下一次动画(此时与异步有关)。以此循环。
该案例中的几个重要部分:
① 不需要使用定时器,直接在本次动画结束后调用下一次动画即可
② 在选择动画函数时,用当前展示的图片对应的index%3(有三种动画函数),选择碎片集合时也用当前展示的图片对应的index
%3,选择图片时,由于图片地址是从下标1开始的,且当前index为即将展示图片的前一个图片元素对应的索引。故当选择图片时,需要给当前索引+2
,从而获取到即将展示图片的正确url
(当当前展示的图片为最后一张图片时,即将展示的图片则为索引为0的图片元素,此时在选择图片时,应作相应的变化)
③ 当所有碎片的opacity
变为1后,重新设置a
集合所有元素的zIndex
:可在遍历a
集合后调用last()
方法,再调用queue()
方法
④ 大爆炸动画:先将碎片的宽和高设为0,将所有碎片集中在最中间(从中间散开),不透明度设为0。随机生成每个碎片的延迟时间,遍历碎片集合,在每个碎片的延迟时间后设置其宽、高、位置和不透明度。当所有碎片显示后重新设置a
集合的每个元素的zIndex
。
完整代码
.all{
position: relative;
}
.imageList{
position: absolute;
margin:auto
}
.imageList>a{
position:absolute;
}
.imageList>a>img{
position: absolute;
width: 100%;
height: 100%;
}
.smallList{
position: absolute;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="slider.css" rel="stylesheet">
</head>
<body>
<div class="all">
<img src="../img/demo1.jpg"/>
<img src="../img/demo2.jpg"/>
<img src="../img/demo3.jpg"/>
<img src="../img/demo4.jpg"/>
<img src="../img/demo5.jpg"/>
<img src="../img/demo6.jpg"/>
</div>
</body>
<script src="../js/jquery-3.0.0.js"></script>
<script src="slider.js"></script>
<script>
$(function () {
$(".all").MySlider({
width: 1000,
height: 400,
time: 1500,
animate: ["fadeTopLeft", "fadeTopBottom", "boom"],
speed: 1300
});
})
</script>
</html>
(function ($) {
$.fn.MySlider = function (options) {
var that = this;//调用该方法的jQuery对象
var items ={
width: 500,
height: 200,
time: 1500,
animate: ["fade"],
speed: 800
};
var obj = $.extend({},items,options);
$.fn.info.opt = obj;
$.fn.info.obj = that;
$.fn.info.len = that.children().length;
this.create(obj,that);
this.start.call(this);
};
$.fn.info={
animateHtml:[],
obj:{},
opt:{},
len:0
};
$.fn.start = function(){
var that = this;
var nowIndex;
that.find(".imageList").children().each(function (index,val) {
if($(this).css("zIndex")==that.info.len-1){
nowIndex = index;
that.animateOpt(that,nowIndex);
}
});
};
$.fn.setStage= function (index,imgIndex) {
//设置当前碎片模块
var str = this.info.animateHtml[index];
$(".smallList").children().remove();
if(imgIndex>4){
imgIndex = -1;
}
$(".smallList").append(str).children().css({
backgroundImage:"url(../img/demo"+(imgIndex+2)+".jpg)",
opacity:0
});
};
$.fn.animateOpt = function(obj,preIndex){
var opt = obj.info.opt;
obj.animateChoose[opt.animate[preIndex%3]].call(obj,preIndex);//用上一个index值求下一个图片对应的动画
};
$.fn.setZIndex = function(obj){
var currentIndex;
$.each($(".imageList").children(),function (index) {
var zIndex = $(this).css("zIndex");
zIndex++;
if (zIndex >= obj.info.len) {
zIndex = 0;
}
if(zIndex==obj.info.len-1){
currentIndex = index;
$(this).fadeIn().animate({
zIndex:zIndex
},function () {
//异步,当遍历完数组后输出1111
console.log(1111)
obj.animateOpt(obj,currentIndex);
});
}else{
console.log(index)
$(this).fadeOut().css({
zIndex:zIndex
});
}
});
};
//不需要使用定时器,直接在一次动画结束后调用下一次动画即可
$.fn.animateChoose={
"fadeTopLeft":function(){
var preIndex = arguments[0];
var obj = this;
obj.setStage.call(obj,preIndex%3,preIndex);
$(".smallList").children().each(function (index) {
//该延迟不是上一个模块出来后延迟,而是相对于之前动画的延迟时间
$(this).delay(40*index).animate({
opacity:1
})
}).last().queue(function () {
//先执行小瓷片动画,再设置ceng,
obj.setZIndex(obj);
});
},
"fadeTopBottom":function () {
var preIndex = arguments[0];
var obj = this;
obj.setStage.call(obj,preIndex%3,preIndex);
$(".smallList").children().each(function (index) {
//该延迟不是上一个模块出来后延迟,而是相对于之前动画的延迟时间
$(this).delay(70*index).animate({
opacity:1
})
}).last().queue(function () {
obj.setZIndex(obj);
});
},
"boom":function () {
var preIndex = arguments[0];
var obj = this;
obj.setStage.call(obj,preIndex%3,preIndex);
$(".smallList").children().css({
width:0,
height:0,
left:obj.info.opt.width/2,
top:obj.info.opt.height/2,
opacity:0
}).each(function (index) {
var width = 50;
var height = 50;
var wnum = obj.info.opt.width/width;
var hnum = obj.info.opt.height/height;
var left = (index%wnum)*width;
var top = Math.floor((index/wnum))*height;
var delayTime = Math.random()*(obj.info.opt.speed)/5
$(this).delay(delayTime).animate({
width:width,
height:height,
left:left,
top:top,
opacity:1
})
}).last().queue(function () {
obj.setZIndex(obj);
});
}
};
$.fn.create = function (items,ele) {
//创建图片集合
var imageList = $("<div></div>");
var imgLength = ele.children().length;
imageList.css({
width: items.width,
height:items.height
}).addClass("imageList");
$.each(ele.children(),function (index,val) {
var aEle = $("<a href='#'></a>");
aEle.css({
width: items.width,
height:items.height,
zIndex:imgLength - index-1
});
aEle.append($(this));
aEle.appendTo(imageList);
});
ele.append(imageList);
//创建碎片
var smallItem = $("<div></div>");
smallItem.css({
width: items.width,
height:items.height,
zIndex:imgLength
}).addClass("smallList");
var x = 20;
var y = 8;
var rowItem="";
var columnItem="";
var squareItem="";
//纵轴
for(var i = 0;i<x;i++){
var str = "<div style='position: absolute;width:"+items.width/x+"px;height:100%;left:"+(items.width/x*i)+"px;background-size:"+items.width+"px "+items.height+"px;background-position: "+(-items.width/x)*i+"px 0px'></div>";
rowItem +=str;
}
this.info.animateHtml.push(rowItem);
for(var j = 0;j<y;j++){
var str = "<div style='position: absolute;width: 100%;height: "+items.height/y+"px;top:"+(items.height/y*j)+"px;background-size:"+items.width+"px "+items.height+"px;background-position:0px "+(-items.height/y)*j+"px'></div>";
columnItem +=str;
}
this.info.animateHtml.push(columnItem);
for(var i=0;i<y;i++){
for(var j=0;j<x;j++){
var str = "<div style='position: absolute;width:"+items.width/x+"px;height: "+items.height/y+"px;left:"+(items.width/x*j)+"px;top:"+(items.height/y*i)+"px;background-size:"+items.width+"px "+items.height+"px;background-position:"+(-items.width/x)*j+"px "+(-items.height/y)*i+"px'></div>";
squareItem +=str;
}
}
this.info.animateHtml.push(squareItem);
ele.append(smallItem)
}
})(jQuery);