聊一下心得:css写得好,真的可以省很多js代码哈,写起来也简单很多,所以要好好掌握js哈,所以这里也提供了css代码,如果您觉得您的css写得不错,可以直接看js代码哦
效果:
1、点击Start View进入照片墙
2、只有一张图片是在中间显示,其他图片在中间的图片两侧随机排序,并且随机旋转一定的角度,层级也是随机的哦
3、点击上面的导航条,可以让对应的图片在中间显示
4、点击中间的图片该照片翻转,显示背面(照片的描述信息)
实现过程:
1、用数据生成结构(模拟的数据,此处不再提供)
2、对所有图片进行排序
3、计算两侧图片的随机范围
4、控制图片翻转
5、控制导航按钮切换图片
6、遮罩层动画实现
html代码:
<body> <div class="photo_wall"> <div class="photo"> <!-- 每张图片的最外层,用来控制图片的旋转和位移 --> <div class="photo_i front" id="photo_{{id}}"> <!-- 内层用来控制图片的3D翻转 --> <div class="photo_3d"> <!-- 每个照片的正面 --> <div class="photo_side photo_front"> <p><img {{src}}="{{img}}"></p> <h3>{{caption}}</h3> </div> <!-- 每个照片的反面 --> <div class="photo_side photo_back"> <p class="desc">{{desc}}</p> </div> </div> </div> {{split}} <div class="nav"><span class="nav_i" id="nav_{{id}}"></span></div> </div> <div class="shade"> <div class="start">Start View</div> </div> </div> </body>
css代码:
/*最外层样式*/ .photo_wall{ width: 100%; height: 600px; position: relative; background: url(../imgs/bg.jpg) no-repeat center center; background-size: cover; overflow: hidden; } /*照片区域的样式*/ .photo { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 1; opacity: 0; transition: 1s; } /*每个照片的样式*/ .photo .photo_i,.photo .photo_3d,.photo .photo_side { width: 336px; height: 392px; position: absolute; left: 0; top: 0; } .photo .photo_i { transition: 800ms; perspective: 750px; left: 50%; top: 50%; transform: translate(-50%,-50%) scale(.5) rotate(0); } .photo .photo_3d { transition: 500ms; transform-style: preserve-3d; transform-origin: 0 50%; } /*正面和反面的公共样式*/ .photo .photo_side { border-radius: 6px; background: #fff; padding: 26px 24px; box-sizing: border-box; backface-visibility: hidden; } /*照片的正面样式*/ .photo .photo_front { transform: rotateY(0); } .photo .photo_front p { width: 286px; height: 286px; border: 2px solid #d8536d; overflow: hidden; display: flex; /*align-items: center;*/ } .photo .photo_front p img{ width: 100%; align-self: center; } .photo .photo_front h3{ width: 166px; height: 44px; background: #d8536d; border-radius: 0 0 6px 6px; margin: 0 auto; text-align: center; font: 16px/44px Arial; color: #fff; } /*照片的反面样式*/ .photo .photo_back { transform: rotateY(-180deg); } .photo .photo_back .desc { font-size: 14px; line-height: 20px; color: #d8536d; } .photo .photo_back a { color: #d8356d; } /*照片的居中样式*/ .photo .center { z-index: 9999; left: 50%; top: 50%; transform: translate(-50%,-50%) scale(1) rotate(0); } /*照片正面的class*/ .photo .front .photo_3d { transform: translateX(0) rotateY(0); } /*照片反面的calss*/ .photo .back .photo_3d { transform: translateX(100%) rotateY(-180deg); } /*导航栏的样式*/ .nav { position: absolute; left: 0; top: 0; z-index: 888; width: 100%; height: 200px; padding-top: 10px; box-sizing: border-box; text-align: center; background: -webkit-linear-gradient(top,rgba(0,0,0,.5),transparent); } @font-face { font-family: "icont"; src: url(../font/iconfont.woff) format("woff"); } .nav .nav_i { display: inline-block; width: 30px; height: 30px; border-radius: 50%; background: rgba(255,255,255,.5); font-family: "icont"; text-align: center; line-height: 30px; color: rgba(255,255,255,0); cursor: pointer; transform: scale(.5); transition: 500ms; } .nav .active { color: rgba(255,255,255,1); transform: scale(.9) rotateY(0); } .nav .back { transform: scale(.8) rotateY(-180deg); } /*遮罩层*/ .photo_wall .shade { position: absolute; left: 0; top: 0; z-index: 2; width: 100%; height: 100%; background: rgba(255,255,255,.7); display: flex; justify-content: center; align-items: center; } .photo_wall .hide { transition: 1s; opacity: 0; transform: scale(0) rotateY(360deg); } .photo_wall .shade .start { width: 200px; height: 60px; border: 2px solid #d8536d; border-radius: 10px; background: rgba(248,229,227,.5); text-align: center; font: 22px/60px Arial; cursor: pointer; }
js代码:用到了我昨天在博客上写的工具函数:
// 用来获取元素 // 用来判断某个元素是否有某个class // 如果没有添加 // 如果有就删除 //获取元素id class tag all function M(sele) { var first = sele.substr(0,1), isArr = sele.split(' ');//id class tag if(first==="#"&&isArr.length==1){//id return document.getElementById(sele.substr(1)); }else{ var arr = Array.from(document.querySelectorAll(sele)); return arr.length == 1?arr[0] :arr; } } //判断某个元素是否包含某个class function hasClass(obj,cls){ var re = new RegExp(`\\b${cls}\\b`); if(re.test(obj.className)){ return true; }else{ return false; } } //给某个元素添加class function addClass(obj,cls){ if(!hasClass(obj,cls)){ obj.className += ` ${cls}`;//不要忘了前面的空格哈 } obj.className = obj.className.trim();//去掉前后空格 } //给某个元素删除class function rmClass(obj,cls){ var re = new RegExp(`\\b${cls}\\b`); if(hasClass(obj,cls)){ obj.className = obj.className.replace(re,'') .replace(/\s{2}/,' ').trim();//去掉前后空格 } }
提供主要的实现步骤的js代码:
(function () {
//---------------------------------------------------------
// 初始化数据
var data = dataList,len = data.length;
createPhotos(data);
var n = 0;
//---------------------------------------------------------
// 基本逻辑
M('.shade .start').addEventListener('click',function() {
addClass(M('.shade'),'hide');
M('.photo').style.opacity = 1;
addClass(M(`#photo_0`),'center');
setTimeout(function(){
sortImgs(n);
}, 200);
});
M('.nav_i').forEach((item,i)=>{
item.onclick = function(){
turnImg(M(`#photo_${i}`));
};
});
//---------------------------------------------------------
// 需求函数化
// 需求1:利用数据生成所有html结构
function createPhotos(data) {
var photo_html = M('.photo').innerHTML.split('{{split}}')[0].trim(),
nav_html = M('.nav').innerHTML.trim();
var photos = [],nav = [];
data.forEach((item,i)=>{
var photoTemp = photo_html.replace(/{{id}}/,i)
.replace(/{{src}}/,'src')
.replace(/{{img}}/,item.img)
.replace(/{{caption}}/,item.caption)
.replace(/{{desc}}/,item.desc),
navTemp = nav_html.replace(/{{id}}/,i);
photos.push(photoTemp);
nav.push(navTemp);
});
photos.push(`<div class="nav">${nav.join('')}</div>`);
M('.photo').innerHTML = photos.join('');
}
// 需求2:给所有的图片排序
function sortImgs(n) {
var photos = M('.photo_i');
initPhotos(photos);
var center = photos.splice(n,1)[0];
addClass(center,'center');
addClass(M(`#nav_${n}`),'active');
// center.addEventListener('click', function(e){
// turnImg(this);
// });
center.onclick = function () {
turnImg(this);
};
// 对剩余的图片进行随机排序
photos.sort(()=>{
return 0.5 - Math.random();
})
var rP = scope(); //返回左右两侧范围 从 x - y
// 分成左侧和右侧两部分
var left = photos.splice(0,Math.ceil((len-1)/2)),
right = photos;
left.forEach((item,i)=>{
item.style.zIndex = rn([0,len]);
item.style.left = rn(rP.L.x) + 'px';
item.style.top = rn(rP.L.y) + 'px';
item.style.transform = `translate(0,0) scale(.9) rotate(${rn([-2160,2160])}deg)`;
});
right.forEach((item,i)=>{
item.style.zIndex = rn([0,len]);
item.style.left = rn(rP.R.x) + 'px';
item.style.top = rn(rP.R.y) + 'px';
item.style.transform = `translate(0,0) scale(.9) rotate(${rn([-2160,2160])}deg)`;
});
}
// 需求3 编写某个区间的随机整数
function rn(arr) {
var max = Math.max.apply(null,arr),
min = Math.min.apply(null,arr);
var p = Math.round(Math.random() * (max - min) + min);
//?;
return p;
}
// 需求4 计算随机的范围
function scope() {
var outer = M('.photo_wall');
var pic = M(`#photo_${rn([0,len-1])}`);
var W = outer.clientWidth,
H = outer.clientHeight,
w = pic.offsetWidth,
h = pic.offsetHeight;
console.log(W,w);
var data = {
L:{
x:[-w/3,W/2 - w/2 - w],
y:[-h/3,H - h*2/3]
},
R:{
x:[W/2 + w/2,W - w*2/3],
y:[-h/3,H - h*2/3]
}
}
return data;
}
// 需求5:控制图片翻转
function turnImg(ele) {
var cur = ele.id.split('_')[1];
var nav = M(`#nav_${cur}`);
if(!hasClass(ele,'center')){ //如果点的不是当前对应的按钮就重新排序
return sortImgs(cur)
}
if(hasClass(ele,'front')){
//翻转到背面
console.log('现在是正面准备移除front');
addClass(ele,'back');
console.log(ele.className);
rmClass(ele,'front');
console.log(ele.className);
addClass(nav,'back');
}else{
//翻转到正面
console.log('现在是反面准备移除back');
addClass(ele,'front');
console.log(ele.className);
rmClass(ele,'back');
console.log(ele.className);
rmClass(nav,'back')
}
}
// 需求6 初始化所有样式
function initPhotos(objs) {
objs.forEach((item,i)=>{
if(hasClass(item,'center')){
var nav = M(`#nav_${i}`);
rmClass(item,'center');
rmClass(item,'back');
addClass(item,'front');
rmClass(nav,'active');
rmClass(nav,'back');
item.onclick = null;
}
item.style.left = '';
item.style.top = '';
item.style.zIndex = '';
item.style.transform = `translate(-50%,-50%) scale(1.1) rotate(0deg)`;
});
}
})()
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持前端开发者。
评论前必须登录!
注册