
解析:
创建列 DIV:
- 从上图中我们能看出,每次旋转的动画是由多列小卡片组成的;
- 每列根据它的下标,对背景进行位移,做到拼接的效果,整体看起来就成了一张图
- 一起来看一下真像是啥样的:

colNode(){ //生成列的节点 for (var i=0;i<this.colLen;i++){ let iDivCol = document.createElement('div'); //列 iDivCol.className = "div-col"; iDivCol.style.width = this.colW+'px'; iDivCol.style.height = this.cubeH+'px'; iDivCol.style.zIndex = (i>this.colLen/2?this.colLen-i:i); this.swiperEle.appendChild(iDivCol); } }
立体感的构成 :
- 旋转的立体感是如何构成的呢?
- 原理其实很简单,可以理解成每列都是一个
立体魔方,它们都是相互独立的, - 每列 backgroundPosition:index*xcolW,进行一个位移,
- 简单来说,即每列内部都有 6 个面组成,每个面都以父级为目标进行 position、transform 等设置,
- 一张图,让你看懂全世界:—— 图五为完成输出

//——[正、上、左、右]
for(var i = 0;i<4;i++){
let dividingLine = i<2;
let span = document.createElement('span');
span.className = ${dividingLine?'bg-img':'pure-color'} i${i};
span.style.width = ${dividingLine? this.colW:this.cubeH}px;
span.style.height = this.cubeH+'px';
if(dividingLine){
span.style.backgroundPosition = -${index*this.colW}px 0;
};
iDivCol.appendChild(span);
};
单列的布局结构 :
zIndex


/四个面的样式/ ...省略 N 行 .div-col span.i1{ /top/ transform-origin:top; transform:translateZ(-360px) rotateX(90deg); } .div-col span.i2{ /left/ transform-origin: left; transform: rotateY(90deg); } .div-col span.i3{ /right/ transform-origin:left; transform:translateX(25px) rotateY(90deg); }

切换 :
div-col transform-origin:50% 50% -180px

- 鼠标经过都实现了,上下页切换还远吗?
- 之前创建结构的时候,我们已知 div 的列数,
- 为了更好的装 B,我们在旋转的时候,给每列都要添加一定延时
setTimeout,得以达到缓冲的视差, - 然后
requestAnimationFrame就该它出场了,setInterval已经成为过去式, - 同时旋转前,还要设置下一页,要显示的图片,
- 当然记得旋转完成,后要重置角度哦。


...省略 N 行
swiperAnimate(){
const requestAnimationFrame = window.requestAnimationFrame||window.WebkitRequestAnimationFrame;
const iDivCol = this.swiperEle.querySelectorAll(".div-col");
for(var i=0;i<iDivCol.length;i++){
//让动画更逼真,给个过渡,当然也可以调整,requestAnimationFrame 每次递增的值,
iDivCol[i].style.WebkitTransition=.8s -webkit-transform ease;
iDivCol[i].style.WebkitTransformOrigin=iDivCol[i].style.transformOrigin = "50% 50% -180px";
this.animateMove(iDivCol[i],i,requestAnimationFrame);
}
}
animateMove(Col,index,animationFrame){
let ColNum =0;
let spanSurface = Col.querySelectorAll("span");
//即将旋转到的面,展示的图片
spanSurface[1].style.backgroundImage="url(./2.jpg)";
setTimeout(()=>{
//每列进行一个延时,以达到缓冲效果
this.rotate(Col,0,spanSurface,animationFrame);
},index*this.delayMilli);
} ...省略 N 行
上下翻页 :
- 上面基本已实现了旋转的效果,再加一些修饰,
- 上下点击切换的功能,注意的地方在于,防止重复点击,当前旋转中时不能点:
pageDown(){ if(this.status){ console.log("下翻,不能点击") return ; }; this.status = 1; this.pageNum = this.pageNum>=this.imageList.length ? 1 :++this.pageNum; this.swiperAnimate(); }

预加载 :
- 因轮播图图片较多,且此示例的图片每次只加载了两张,故要对图片进行一个预加载,
- 以及图片加载出错后的过滤,避免影响后续效果的呈现:
preloadingImage(){ this.imageList.map((k,v)=>{ let imgNode = new Image(); imgNode.onerror=err=>{ this.imageList.splice(v,1); } imgNode.src = k; }); }

总结:
一个效果实现的方式有很多种,比如我们可以设置 6 个面,每设置一次,都是展示一张图,这样就不用每次旋转完后又去重置图片、角度等问题,包括 requestAnimationFrame 动画切换的过渡过程,也应该有更好的方式,欢迎各位大佬指点。以上就是今天为您带来的分享,你 GET 到了吗?如果觉得不错,记得给个赞哦
