js+css3 3D倾斜图片列表布局点击放大切换特效

style.css代码:

body,p{
	margin: 0;
}
ul{
	margin: 0;
	padding: 0;
	list-style: none;
}
img{
	border: none;
	vertical-align: middle;
}
body{
	background: #000000;
	color: #fff;

	overflow-x: hidden;	/* 旋转后会出现横向的滚动条 */
}





/*works*/
#wrap{margin-top: 150px}
#wrap ul{
	width: 1050px;
	margin: 0 auto;
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;

	transform-style: preserve-3d;	/* 自己变成3d的空间是为了图片像弹簧一下能出来,加不加景深都可以,加了会视觉冲击感强烈一点 */
	transform: translateY(-15%) rotateX(45deg) rotateZ(45deg);	/* 先往右转45deg,斜着(wtud3)了,再往后一把推倒(旋转Z轴45deg) */
}
#wrap li{
	width: 330px;
	height: 230px;
	margin-bottom: 30px;
	position: relative;
	background: rgba(255,255,255,0.5);	/* 给一个灰色的底色 */
	cursor: pointer;
}
#wrap li img,#wrap li div{
	position: absolute;
	width: 100%;
	height: 100%;
	left: 0;
	top: 0;

	transition: 0.3s;	/* 加上运动效果 */
}
#wrap li img{
	z-index: 2;	/* 把图片放到最上面 */
}
#wrap li div:nth-of-type(1){
	background: #ac5cf5;
	opacity: 0.5;
}
#wrap li div:nth-of-type(2){
	background: #5db4eb;
	opacity: 0.5;
}
#wrap li div:nth-of-type(3){
	background: #5debb4;
	opacity: 0.5;
}

/* 以下为弹簧效果 */
#wrap li:hover{
	box-shadow: 0 0 50px #fff;
}
#wrap li:hover img:nth-of-type(1){
	transform: translateZ(100px);
}
#wrap li:hover div:nth-of-type(1){
	transform: translateZ(75px);
}
#wrap li:hover div:nth-of-type(2){
	transform: translateZ(50px);
}
#wrap li:hover div:nth-of-type(3){
	transform: translateZ(25px);
}


#shadowBox{
	width: 100%;
	height: 2000px;
	background: rgba(0,0,0,0.5);
	position: absolute;
	left: 0;
	top: 0;
	
	opacity: 0;
	transition: 0.5s;
	display: none;	/* 不设置为none的话,它会档住图片 */
}
#showPic{
	width: 600px;
	height: 400px;
	box-shadow: 0 0 50px #000;
	position: fixed;

	left: 0;
	top: 0;
	right: 0;
	bottom: 0;
	margin: auto;
	
	opacity: 0;
	transition: 0.5s;
	transform: scale(0);	/* 出现的形式是从小到大 */
	display: none;	/* 不设置为none的话它会档住图片 */
	
}
.prev,.next{
	width: 50px;
	height: 45px;
	position: absolute;
	/* top: 50%;
	margin-top: -22px; */
	top: 0;
	bottom: 0;
	margin: auto;
	
	cursor: pointer;
	z-index: 2;
}
.prev{
	left: 0;
	background: url(../img/prev.png);
}
.next{
	right: 0;
	background: url(../img/next.png);
}
#showPic .img{
	position: relative;
	z-index: 1;
	transform-style: preserve-3d;
	perspective: 500px;
	height: 400px;
}
#showPic img{
	width: 600px;
	height: 400px;
	position: absolute;
	left: 0;
	top: 0;
	transition: transform .3s;
}

/* 图片张开时候的变换中心点 */
#showPic img.moveToRight{
	transform-origin: left;
}
#showPic img.moveToLeft{
	transform-origin: right;
}

script.cs代码:

var lis=document.querySelectorAll('#wrap li'),
	shadowBox=document.querySelector('#shadowBox'),
	showPic=document.querySelector('#showPic'),
	prev=document.querySelector('.prev'),
	next=document.querySelector('.next'),
	imgCon=document.querySelector('#showPic .img'),
	bigImgs=imgCon.children;

var curNum=0;	//当前图片的索引
var canClick=true;	//用户是否可以点击


//图片预加载功能函数
function loadImg(imgs,callBack){
	var loadImgs=[],loadImgNum=0;

	for(var i=0;i<imgs.length;i++){
		loadImgs[i]=new Image();
		loadImgs[i].onload=function(){
			loadImgNum++;
			if(loadImgNum==imgs.length){
				callBack(loadImgs);
			}
		};
		loadImgs[i].src=imgs[i];
	}
}
//把所有的图片都获取并存储到一个数组里
var imgs=[];
for(var i=0;i<lis.length;i++){
	imgs.push('img/t'+i+'.png');
}

loadImg(imgs,function(images){
	for(var i=0;i<lis.length;i++){
		lis[i].index=i;
		lis[i].onclick=function(){
			shadowBox.style.height=document.documentElement.offsetHeight+'px';
			shadowBox.style.display=showPic.style.display='block';

			//缩放需要一个过程,所以让它延迟一会再出来
			setTimeout(function(){
				shadowBox.style.opacity=showPic.style.opacity=1;
				showPic.style.transform='scale(1)';
			},50);

			//把点击的那个索引更新给curNum
			curNum=this.index;

			bigImgs[1].src=images[curNum].src;	//弹出层出来以后,前面那张图片应该是点击对应的那个图。此时后面那张图要改么?不需要。它应该在点击的时候确定,往右走与往左走是不一样的。

			nextClick(images);
			prevClick(images);
		};
	}
});

//鼠标点击遮罩(yalh)层,隐藏弹出层
shadowBox.addEventListener('click',function(){
	//如果点击遮罩层的时候正在运动,那就禁止用户点击,只有在运动停止的时候才能点击。这一点最后说
	if(!canClick){
		return;
	}

	shadowBox.style.display=showPic.style.display='none';
	shadowBox.style.opacity=showPic.style.opacity=0;
	showPic.style.transform='scale(0)';
});

//下一张点击
function nextClick(images){
	var nextNum=0;	//下一张图片的索引(背后那张图片的索引)

	next.onclick=function(){
		if(!canClick){
			return;
		}
		canClick=false;	//点击后立马变成false,再书合上后再变成true,只有为true的时候才能点
		/*
			点击的时候要做的事情
				1、背后图片的地址要换成正确的
				1、上面的图片走到右边
				2、下面的图片像翻书(tonn)一样打开(上一步结束后进行)
				3、上面的图片回到原始位置、下面图片合上(上一步结束后进行)
		 */


		//往右点击后下一张图片的索引是当前图片的索引+1
		nextNum=curNum+1;
		if(nextNum==lis.length){	//走到最后了,再回到起点
			nextNum=0;
		}
		bigImgs[0].src=images[nextNum].src;	//换后面那张图片的地址

		

		var endNum1=0;	//记录上面图片运动结束的次数
		var endNum2=0;	//记录下面图片运动结束的次数
		

		bigImgs[0].className=bigImgs[1].className='moveToRight';	//上面图往右走、下面图张开的时候,旋转不太对劲,是因为旋转中心没有设置
		bigImgs[1].style.transform='translateX(600px) rotateY(-10deg)';	//上面图片往右走
		bigImgs[1].addEventListener('transitionend',function(){	//上面图片已经走到右边了
			endNum1++;

			bigImgs[0].style.transform='rotateY(-10deg)';	//下面图张开
			bigImgs[1].style.transform='translateX(0) rotateY(0deg)';	//上面图回去


			/*
				这里要注意
					1、按正常的逻辑应该是上面的图回去了,然后下面图上再合上。所以需要知道什么时候上面的图回去了
					2、可能大家会再来个transitionend方法,其实不需要
					3、先在这里console.log(1),看到会弹出两次
					3、在外面声明一个变量,用来存储结束事件发生的次数,当这个数字加到2的时候就代表上面的图片回去的结束事件发生了
			 */
			if(endNum1==2){	//这个条件成立说明,现在是上面的图上已经回到原点了
				bigImgs[0].style.transform='rotateY(0)';	//下面的图合上
				bigImgs[1].style.zIndex=1;	//上面的图跑后面
				bigImgs[0].style.zIndex=2;	//下面的图跑前面
			}
		});


		//下面的图合上了
		bigImgs[0].addEventListener('transitionend',function(){
			//这里也会发生两次,因为下面的图,张开又合上,是两次过渡
			//console.log(1);

			endNum2++;
			if(endNum2==2){	
				/* 
					1、这个条件成立,说明现在的end事件对应的是书合上的过渡
					2、这里需要做两件事件
						1、更改当前图片的索引,下一张的索引在函数一开始就修改了
						2、还原图片的层级到初始状态
				 */
				//书合上了,也代表一次完整的运动走完了,然后就要改索引了。这里只需要
				curNum++;
				if(curNum==lis.length){	//走到最后了,再回到起点
					curNum=0;
				}

				bigImgs[0].style.zIndex=1;	//后面图片的zIndex
				bigImgs[1].style.zIndex=2;	//前面图片的zIndex,既然层级变了,那图片的路径也要变
				bigImgs[1].src=images[nextNum].src;	//只用变前面那张图片的地址,变成下一张图片的地址

				canClick=true;	//书合上了,才可以进行下次的点击
			}
		})
	};
}

//上一张点击
function prevClick(images){
	var prevNum=0;	//修改

	prev.onclick=function(){	//修改
		if(!canClick){
			return;
		}
		canClick=false;

		//这一块全部修改
		prevNum=curNum-1;
		if(prevNum==-1){
			prevNum=lis.length-1;
		}
		bigImgs[0].src=images[prevNum].src;

		

		var endNum1=0;
		var endNum2=0;
		

		bigImgs[0].className=bigImgs[1].className='moveToLeft';	//修改
		bigImgs[1].style.transform='translateX(-600px) rotateY(10deg)';	//修改
		bigImgs[1].addEventListener('transitionend',function(){
			endNum1++;

			bigImgs[0].style.transform='rotateY(10deg)';	//修改
			bigImgs[1].style.transform='translateX(0) rotateY(0deg)';


			if(endNum1==2){
				bigImgs[0].style.transform='rotateY(0)';
				bigImgs[1].style.zIndex=1;
				bigImgs[0].style.zIndex=2;
			}
		});


		bigImgs[0].addEventListener('transitionend',function(){
			endNum2++;
			if(endNum2==2){

				//这一块修改
				curNum--;
				if(curNum==-1){
					curNum=lis.length-1;
				}

				bigImgs[0].style.zIndex=1;
				bigImgs[1].style.zIndex=2;
				bigImgs[1].src=images[prevNum].src;	//修改

				canClick=true;
			}
		})
	};
}

HTML代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>js+css3 3D倾斜图片列表布局点击放大切换特效</title>
		<link rel="stylesheet" href="css/style.css" />
	</head>
	<body>
		<div id="wrap">
			<ul>
				<li>
					<img src="img/t0.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
				<li>
					<img src="img/t1.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
				<li>
					<img src="img/t2.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
				<li>
					<img src="img/t3.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
				<li>
					<img src="img/t4.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
				<li>
					<img src="img/t5.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
				<li>
					<img src="img/t6.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
				<li>
					<img src="img/t7.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
				<li>
					<img src="img/t8.png" alt="">
					<div></div>
					<div></div>
					<div></div>
				</li>
			</ul>
		</div>
			
		<div id="shadowBox"></div>
		
		<div id="showPic">
			<div class="prev"></div>
			<div class="img">
				<img style="z-index: 1;" src="img/t0.png"/>
				<img style="z-index: 2;" src="img/t1.png"/>
			</div>
			<div class="next"></div>
		</div>
		<script type="text/javascript" src="js/script.js" ></script>
	</body>
</html>

img文件夹下任意九张图片t0.png到t9.png和两张切换图片prev.png、next.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值