在该笔记中将学到列表展示中散列画廊特效的方法与展示效果
本系列的是参考慕课网 Lyn老师的视频,仅供个人查阅使用,具体讲解推荐参考视频。
显示效果如下:
其中,点击屏幕下部的按钮,可以实现居中照片的切换。点击屏幕中的照片,也可以控制照片正反面的切换动画。
VCD 分解
1.View
:视觉,是 HTML + CSS,基本界面模版
Controller
:控制,JavaScript,内容处理,事件处理Data
:数据,data.js,非必须,助于理解
视觉部分
数据部分
有一个 data.js 来处理所有的海报图片链接、标题、描述
控制部分
控制海报的批处理,分配海报的位置,设置控制条的动作,海报的翻面控制。
使用 -webkit-perspective:800px
设置子元素对 3D 效果的支持。这里设置的是子元素距离视图的位置
使用 -webkit-backface-visibility:hidden
设置元素不面向屏幕的时候进行隐藏
使用 -webkit-transform-style:preserve-3d
设置支持子元素的 3D 效果
-webkit-transform: rotateY(0deg)
定义元素旋转的角度
使用 transition
设置过渡动画
计算周围海报的位置范围
为了不让周围的海报随机显示的时候,不要太超出边界,或者不要太遮挡中间的海报,所以计算海报随机位置的时候,需要给出一个范围
<html>
<head>
<meta charset="utf-8">
<title>海报画廊</title>
<style type="text/css">
*{padding: 0; margin: 0;font-size: 14px;}
body{border: 1px solid rebeccapurple;}
.wrap{width: 800px;height: 400px;margin: 100px auto;border: 1px solid rebeccapurple;overflow: hidden;
perspective: 800px;-webkit-perspective:800px;background-color: #666}
.photo{width: 160px;height: 190px;position: absolute;box-shadow: 0 0 1px rgba(0, 0, 0, 0.01);cursor: pointer;transition: all 0.5s;}
.photo .side-front{padding: 10px;position: absolute;}
.photo .side-front img{width: 140px;height: 150px;display: block;margin: 0 auto;border: 1px solid #aaa;}
.photo .side-front p{display: block;height: 30px;line-height: 30px;text-align: center;color: #333;font-size: 12px}
.photo .side-back{padding: 10px;position: absolute;width: 140px;height: 170px;overflow: hidden;background-color: #ddd;}
.photo .side-back p{color: #666;font-size: 12px;line-height: 1.5em;}
.photo-center{top: 50%; left: 50%;margin: -80px 0 0 -95px;-webkit-transform: rotateY(0deg);z-index: 1;}
/*设置图片旋转的效果*/
.photo-wrap{-webkit-transform-style: preserve-3d;-webkit-backface-visibility: hidden;width: 100%;height: 100%;transition: all 0.6s;border: 1px solid #aaa;}
.photo-wrap .side-front{-webkit-transform: rotateY(0deg);}
.photo-wrap .side-back{-webkit-transform: rotateY(180deg);}
.photo-f .photo-wrap{-webkit-transform: rotateY(0deg);}
.photo-b .photo-wrap{-webkit-transform: rotateY(180deg);}
.nav{width: 100%;height: 26px;line-height: 26px;position: absolute; bottom: 36px;text-align: center;}
.nav-i{display: inline-block;background-color: #333;width: 26px;height: 26px;border-radius: 13px;margin:0 10px;cursor: pointer;transform: scale(0.5);}
.nav-current{transform: scale(0.8);}
</style>
<script>
function turnPage(elem){
let className = elem.className;
if(/photo-f/.test(className)){
className = className.replace("photo-f", "photo-b");
} else {
className = className.replace("photo-b", "photo-f");
}
elem.className = className;
}
function randomInt(min, max){
let diff = max-min+1;
return Math.ceil(Math.random()*diff + min - 1);
}
function randomArray(arr){
let rArr = [];
do{
let index = randomInt(0, arr.length-1);
rArr.push(arr.splice(index,1).pop());
}while(arr.length>0)
return rArr;
}
function range(){
let range = { left:{x:[], y:[]}, right:{x:[], y:[]}};
let wrap = {
width:document.getElementById("wrap").clientWidth,
height:document.getElementById("wrap").clientHeight
};
let photo = {
width:document.getElementsByClassName("photo")[0].clientWidth,
height:document.getElementsByClassName("photo")[0].clientHeight
};
range.left.x.push(0-photo.width/2);
range.left.x.push(wrap.width/2-photo.width);
range.left.y.push(0-photo.height/2);
range.left.y.push(wrap.height-photo.height/2);
range.right.x.push(wrap.width/2+photo.width/2);
range.right.x.push(wrap.width-photo.width/2);
range.right.y.push(0-photo.height/2);
range.right.y.push(wrap.height-photo.height/2);
return range;
}
//根据index 选择对应的 photo,index的值从1-data.length
function setCenter(index){
let photos = document.getElementsByClassName("photo");
let photo = photos[index-1];
for(let i=0;i<photos.length;i++){
photos[i].className = photos[i].className.replace(" photo-center", "");
photos[i].style.left = "";
photos[i].style.top = "";
photos[i].style['-webkit-transform'] = "rotateY(0deg)";
photos[i].className = photos[i].className.replace(" photo-b", " photo-f");
}
photo.className += " photo-center";
}
function setLeftRight(index){
let r= range();
let _photos = document.getElementsByClassName("photo");
let photos = [];
for (let i=0; i<_photos.length; i++){
if(i!== (index-1))
photos.push(_photos[i]);
_photos[i].className = _photos[i].className.replace(" photo-b", " photo-f");
}
photos = randomArray(photos);
let photoLeft = photos.splice(Math.ceil(photos.length/2), Math.ceil(photos.length/2));
let photoRight = photos;
for(let i=0; i<photoLeft.length; i++){
let photo = photoLeft[i];
photo.style.left = randomInt(r.left.x[0], r.left.x[1]) + "px";
photo.style.top = randomInt(r.left.y[0], r.left.y[1]) + "px";
photo.style['-webkit-transform'] = 'rotate('+randomInt(-60, 60) + 'deg)';
}
for(let i=0; i<photoRight.length; i++){
let photo = photoRight[i];
photo.style.left = randomInt(r.right.x[0], r.right.x[1]) + "px";
photo.style.top = randomInt(r.right.y[0], r.right.y[1]) + "px";
photo.style['-webkit-transform'] = 'rotate('+randomInt(-60, 60) + 'deg)';
}
}
let data = [
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/1.jpg",title : "照片1",desc : "照片1的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/2.jpg",title : "照片2",desc : "照片2的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/3.jpg",title : "照片3",desc : "照片3的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/4.jpg",title : "照片4",desc : "照片4的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/5.jpg",title : "照片5",desc : "照片5的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/6.jpg",title : "照片6",desc : "照片6的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/7.jpg",title : "照片7",desc : "照片7的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/8.jpg",title : "照片8",desc : "照片8的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/9.jpg",title : "照片9",desc : "照片9的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/10.jpg",title : "照片10",desc : "照片10的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/11.jpg",title : "照片11",desc : "照片11的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/12.jpg",title : "照片12",desc : "照片12的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/13.jpg",title : "照片13",desc : "照片13的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/14.jpg",title : "照片14",desc : "照片14的描述"},
{img : "http://ofjjubwp5.bkt.clouddn.com/image/jpg/15.jpg",title : "照片15",desc : "照片15的描述"}
];
window.onload = function(){
//批处理生成照片
let template = document.getElementById("photos").innerHTML;
let navs = document.getElementById("navs");
let navTemplate = navs.innerHTML;
let htmlColl = [];
let navColl = [];
for(let i=0;i<data.length;i++){
let html = template.replace("{{index}}", i+1).replace("{{img}}", data[i].img).replace("{{title}}", data[i].title).replace("{{desc}}", data[i].desc);
htmlColl.push(html);
let nav = navTemplate.replace("{{index}}", i+1);
navColl.push(nav);
}
document.getElementById("photos").innerHTML = htmlColl.join("");
navs.innerHTML = navColl.join("");
let navIs = document.getElementsByClassName("nav-i");
for(let i=0; i<navIs.length; i++){
navIs[i].onclick = function(){
let photos = document.getElementsByClassName("photo");
if(/nav-current/.test(this.className)){
let className = photos[i].className;
if(/photo-f/.test(className)){
photos[i].className = className.replace(" photo-f", " photo-b");
} else{
photos[i].className = className.replace(" photo-b", " photo-f");
}
} else{
let This = this;
let navIs = document.getElementsByClassName("nav-i");
for(let j=0;j<navIs.length;j++){
navIs[j].className = navIs[j].className.replace(" nav-current", "");
}
This.className += " nav-current";
setCenter(i+1);
setLeftRight(i+1);
}
}
}
//在开始的时候,随机选取一张照片放在中间区域
let c = randomInt(1, 8);
setCenter(c);
setLeftRight(c);
}
</script>
</head>
<body>
<div class="wrap" id="wrap">
<!-- photo 负责平移和旋转-->
<div id="photos">
<div class="photo photo-f" onclick="turnPage(this)" id="photo-{{index}}">
<!-- photo-wrap 负责照片的翻转-->
<div class="photo-wrap">
<div class="side-front">
<img src="{{img}}" alt="">
<p>{{title}}</p>
</div>
<div class="side-back">
<p>{{desc}}</p>
</div>
</div>
</div>
</div>
<div class="nav" id="navs">
<i class="nav-i" id="nav-{{index}}"></i>
</div>
</div>
</body>
</html>