酷炫的轮番效果是如何实现的
slide
切换效果)需如下:<div class="container3D">
<div class="wrapper3D">
<div class="slide3D">
<img src="image-slider-1.jpg" alt="" />
</div>
<div class="slide3D">
<img src="image-slider-2.jpg" alt="" />
</div>
<div class="slide3D">
<img src="image-slider-3.jpg" alt="" />
</div>
<div class="slide3D">
<img src="image-slider-4.jpg" alt="" />
</div>
<div class="slide3D">
<img src="image-slider-5.jpg" alt="" />
</div>
</div>
<div class="slide3D-pagination"></div>
<div class="slide3D-prev-button"></div>
<div class="slide3D-next-button"></div>
</div>
flip、turn、flat、fragment
)布局:<div class="container3D">
<div class="wrapper3D"></div>
<div class="slide3D-pagination"></div>
<div class="slide3D-prev-button"></div>
<div class="slide3D-next-button"></div>
</div>
new Slide3D(contianer, params)
初始化一个Slide3D
,返回初始化后的Slide3D
实例。var mySlide = new Slide3D('.flip', {
width: 300, // 定义宽
height: 400, // 定义高
direction: 'horizontal | vertical', // 切换方向,只有slide支持
effect: 'flip', // 切换效果 flip | turn | slide | flat | fragment
sources: ['image-slider-1.jpg', 'image-slider-2.jpg', 'image-slider-3.jpg', 'image-slider-4.jpg', 'image-slider-5.jpg'], // 除“slide”外,其他切换效果都需要sources指定切换图片
box:{ // slide效果不需要
rows: 6, // 行
cols: 3 // 列
},
pagination: true, // 是否添加分页器
loop: true // 是否循环,只有slide选择设置,其他切换效果都是循环
});
slide
切换效果,相信大家对slide
切换效果都会实现,难点在于循环轮番,如何实现呢?wrapper3D
这一层来实现滑动的。if(s.params.loop) {
var firstChild = s.wrapper.firstElementChild.cloneNode(true);
var lastChild = s.wrapper.lastElementChild.cloneNode(true);
s.wrapper.appendChild(firstChild);
s.wrapper.insertBefore(lastChild, s.wrapper.firstElementChild);
s.setTransitionDuration(s.wrapper, 0);
s.currentIndex = 1;
s.slideTo(s.activeIndex + 1);
};
loop
属性为true
时,我们就将第一个slide3D
和最后一个slide3D
的内容复制出来,分别作为最后一个子元素和第一个子元素插入到wrapper3D
元素中。<div class="container3D">
<div class="wrapper3D">
<div class="slide3D">
<img src="image-slider-5.jpg" alt="" />
</div>
/* 这里省略原来的5个slide3D */
<div class="slide3D">
<img src="image-slider-1.jpg" alt="" />
</div>
</div>
/* 省略分页器和前进后退按钮 */
</div>
wrapper3D
元素滑动一个slide3D
元素的宽度,不然你看到的就是最后一张图片了。s.slideTo(s.activeIndex + 1);
s.slideTo = function(index) {
if(s.params.direction == 'horizontal') {
s.setTransform(s.wrapper, 'translate3d(-' + (s.params.width * index) + 'px, 0, 0)');
}
};
wrapper3D
元素的transform
是这样的:transform: translate3d(-400px, 0, 0)
transform: translate3d(-400px, 0, 0) => transform: translate3d(0, 0, 0)
transition-duration
设为0,然后:transform: translate3d(-400 * 5px , 0, 0)
由于transition-duration
等于0,所以切换是瞬间,会欺骗我们的眼睛,我们是看不到它切换的。
slide切换效果的循环就是这样的,当然,还有更多方法,你可以尝试,接下来讲讲其他的切换效果(flip、turn、flat、fragment),它们之间是大同小异的。
首先要做的是给图片分格:
var r = s.params.box.rows;
var c = s.params.box.cols;
var width = Math.ceil(s.params.width / c); // 定义每格宽度
var height = Math.ceil(s.params.height / r); //定义每格高度
var length = total = r * c; // 总格数
var cssText = '';
for(var i = 0; i < length; i++) {
var left = i % c * width;
var top = Math.floor(i / c) * height;
var flipItem = document.createElement('div');
if(s.params.effect == 'fragment') {
cssText += 'opacity:0;';
};
cssText += 'position:absolute;left:' + left + 'px;top:' + top + 'px;';
cssText += 'width:' + width + 'px;height:' + height + 'px;';
cssText += 'background-image:url(' + url + ');';
cssText += 'background-position:-' + left + 'px -' + top + 'px;';
cssText += 'background-size:' + s.params.width + 'px ' + s.params.height + 'px;';
cssText += 'background-repeat:no-repeat;';
flipItem.style.cssText = cssText;
flipItem.change = false;
animation[s.params.effect].execute(flipItem); // 记住这个函数,后面会讲到
s.wrapper.appendChild(flipItem); // 插入
};
估计你看上面的代码会比较乱,原理跟table差不多,相当于一个td对应一个div,自己用代码实现分格试试就知道了。
我们拿fragment
切换效果来分析:
定义一个动画函数:
animate: function(item, fn, fnEnd, index) {
var opacity = 0;
var data = [];
clearInterval(item.timer);
item.timer = setInterval(function() { // 使用计时器来实现动画
opacity += 0.05; // 改变透明度
data['opacity'] = opacity;
data['index'] = index;
if(fn) fn.call(item, data); // 执行fn函数,同时改变fn函数里的this指向和传参
if(opacity >= 1) {
clearInterval(item.timer);
if(fnEnd) fnEnd.call(item); // 当前item满足条件时执行fnEnd函数,也是改变fnEnd函数里的this指向
}
}, 20);
}
对每个item(就是每格)执行动画,同时传参。
animation[s.params.effect].execute(flipItem);
执行的是下面的代码:
(function(item) {
setTimeout(function() {
animation[s.params.effect].animate(item, function(data) {
item.style.opacity = data['opacity']; // 每次setInterval执行的代码
}, function() {
if(--total == 0) { // 当所有item完成动画时,执行if代码块里的代码
s.wrapper.innerHTML = '';
s.lock = false;
end();
s.wrapper.style.backgroundImage = 'url(' + s.params.sources[s.activeIndex] + ')';
}
}, i);
}, i * 50); // 你也可以不适应setTimeout,那样所有item动画都会同时执行
})(item); // 立即执行函数
其他切换效果也是这个原理。
当你理解了原理后,相信你可以开发出更酷炫的效果。
如果有问题,欢迎在下方提问!