css照片墙preserve-3d翻转照片效果

css照片墙preserve-3d翻转照片效果

效果图

请添加图片描述

实现

布局

<body onselectstart="return false;">
	<!--2.改写视图,为模板字符串 -->
	<!-- 放置所有内容 -->
	<div class="wrap" id="wrap">
		<!-- 放置海报 photo这个div用来负责位移和旋转即平面上xy的旋转-->
		<div class="photo photo_front" onclick="turn(this)" id="photo_{
     
     {index}}">
			<!-- photo-wrap这个div用来负责3D翻转 -->
			<div class="photo-wrap">
				<!-- 每个海报都有正反面 -->
				<!-- 海报正面 -->
				<div class="side side-front">
					<!-- 海报图片 -->
					<p class="image"><img src="img/{
     
     {img}}"></p>
					<!-- 海报标题 -->
					<p class="caption">{
   
   {caption}}</p>
				</div>
				<!-- 海报反面说明 -->
				<div class="side side-back">
					<p class="desc">{
   
   {desc}}</p>
				</div>
			</div>
		</div>
	</div>
</body>
  • 其中 id="wrap"{ {}} 用来替换模板
  • 初始化时将模板用图片填充

数据格式

在这里插入图片描述

function addPhotos(){
    
    
	var template = g('#wrap').innerHTML;
	var html = [];
	// 制作导航条
	var nav = [];
	for( s in data){
    
    
		var _html = template
						.replace('{
    
    {index}}',s)
						.replace('{
    
    {img}}',data[s].img)
						.replace('{
    
    {caption}}',data[s].caption)
						.replace('{
    
    {desc}}',data[s].desc);
		html.push(_html);
		// 导航条控制按钮内容
		nav.push('<span id="nav_'+s+'" οnclick="turn(g(\'#photo_'+s+'\'))" class="i">&nbsp;</span>');
	}
	html.push('<div class="nav">'+nav.join('')+'</div>')
	g('#wrap').innerHTML = html.join('');
}
addPhotos();
// 相当于 jQuery 获取元素的作用
function g(selector){
    
    
	var method = selector.substr(0,1) == '.' ? 'getElementsByClassName' : 'getElementById';
	return document[method](selector.substr(1));
}

在这里插入图片描述

  • 初始化时候需要默认显示一个居中图片,剩余的图片需要随机分布在居中图片的两边
function addPhotos() {
    
    
	...
	rsort(random([0,data.length]));
}
// 随机生成一个值
function random(range){
    
    
	var max = Math.max(range[0],range[1]);
	var min = Math.min(range[0],range[1]);
	var diff = max-min;
	// 生成range[0]到range[1]之间的随机数
	var number = Math.ceil(Math.random() * diff + min);
	return number;
}

// 排序海报,以及居中的海报
function rsort(n){
    
    
	var _photo = g('.photo');
	var photos = [];
	for(var s=0;s<_photo.length;s++){
    
    
		_photo[s].className = _photo[s].className.replace(/\s*photo_center\s*/,' ');
		_photo[s].className = _photo[s].className.replace(/\s*photo_front\s*/,' ');
		_photo[s].className = _photo[s].className.replace(/\s*photo_back\s*/,' ');
		_photo[s].className += ' photo_front ';
		_photo[s].style.left = '';
		_photo[s].style.top = '';
		_photo[s].style['transform'] = 'rotate(0deg) scale(1.3)';
		photos.push(_photo[s]);
	}
	var photo_center = g('#photo_'+n);
	photo_center.className += ' photo_center';
	// 在所有的photo中去掉photo_center的那张图
	photo_center = photos.splice(n,1)[0];
	// 把剩下的海报分为左右两个部分
	var photos_left = photos.splice(0,Math.ceil(photos.length/2));
	var photos_right = photos;
	var ranges = range();
	for(s in photos_left){
    
    
		var photo = photos_left[s];
		photo.style.left = random(ranges.left.x)+'px';
		photo.style.top = random(ranges.left.y)+'px';
		// 添加旋转样式
		photo.style['transform'] = 'rotate('+random([-150,150])+'deg) scale(1)';
	}
	for(s in photos_right){
    
    
		var photo = photos_right[s];
		photo.style.left = random(ranges.right.x)+'px';
		photo.style.top = random(ranges.right.y)+'px';
		// 添加旋转样式
		photo.style['transform'] = 'rotate('+random([-150,150])+'deg) scale(1)';
	}
	// 居中的图片对应的按钮样式
	var navs = g('.i');
	for(var s=0;s<navs.length;s++){
    
    
		navs[s].className = navs[s].className.replace(/\s*i_current\s*/,' ');
	}
	g('#nav_'+n).className += ' i_current ';
}
// 计算左右分区图片位置的范围
function range(){
    
    
	var range = {
    
    left:{
    
    x:[],y:[]},right:{
    
    x:[],y:[]}};
	var wrap = {
    
    
		w:g('#wrap').clientWidth,
		h:g('#wrap').clientHeight
	}
	var photo = {
    
    
		w:g('.photo')[0].clientWidth,
		h:g('.photo')[0].clientHeight
	}
	range.wrap = wrap;
	range.photo = photo;
	// 左分区x,y的范围
	range.left.x = [0-photo.w,wrap.w/2-photo.w/2];
	range.left.y = [0-photo.h,wrap.h];
	// 右分区x,y的范围
	range.right.x = [wrap.w/2+photo.w/2,wrap.w+photo.w];
	range.right.y = range.left.y;
	return range;
}
  • 点击图片或者按钮点击的图片需要居中显示
// 翻面控制
function turn(elem){
    
    
	var cls = elem.className;
	var n =elem.id.split('_')[1];
	// 判断点击的图片是否居中显示了,进行排序
	if(!/photo_center/.test(cls)){
    
    
		return rsort(n);
	}
	// .test检查cls字符串中是否有photo_front的字符串
	if(/photo_front/.test(cls)){
    
    
		cls = cls.replace(/photo_front/,'photo_back');
	}else{
    
    
		cls = cls.replace(/photo_back/,'photo_front');
	}
	return elem.className = cls;
}

样式

*{
    
    
	padding: 0;
	margin: 0;
}
body{
    
    
	background-color: #fff;
	color: #555;
	font-family: 'Avenir Next','Lantinghei SC';
}
.wrap{
    
    
	width: 100%;
	height: 800px;
	position:absolute;
	top: 50%;
	margin-top: -400px;
	background-color: #333;
	overflow: hidden;
}
.photo{
    
    
	width: 260px;
	height: 320px;
	position: absolute;
	z-index: 1;
	box-shadow: 0 0 1px rgba(0,0,0,.01);
	transition: all .5s;
}
.photo .side{
    
    
	width: 100%;
	height: 100%;
	background-color: #eee;
	position: absolute;
	top: 0;
	right: 0;
	padding: 20px;
	box-sizing: border-box;
}
.photo .side-front .image{
    
    
	width: 100%;
	height: 250px;
	line-height: 250px;
	overflow: hidden;
}
.photo .side-front .image img{
    
    
	width: 100%;
}
.photo .side-front .caption{
    
    
	text-align: center;
	font-size: 15px;
	line-height: 50px;
}
.photo .side-back .desc{
    
    
	color: #666;
	font-size: 12px;
	line-height: 1.5em;
}
.photo_center{
    
    
	left: 50%;
	top: 50%;
	margin-top: -160px;
	margin-left: -130px;
	z-index: 999;
}
.photo-wrap .side-front{
    
    
	transform: rotateY(0deg);
}
.photo-wrap .side-back{
    
    
	transform:rotateY(180deg);
}
.photo-wrap .side{
    
    
	backface-visibility:hidden; /* 3d 旋转翻面的时,背对的内容不可见 */
}
.photo-wrap{
    
    
	position: absolute;
	width: 100%;
	height: 100%;
	transform-origin: 0% 50%;
	transform-style: preserve-3d;
	transition: all .6s;
}
.photo_front .photo-wrap{
    
    
	transform: translate(0px,0px) rotateY(0deg);
}
.photo_back .photo-wrap{
    
    
	transform: translate(260px,0px) rotateY(180deg);
}
.nav{
    
    
	width: 80%;
	height: 30px;
	line-height: 30px;
	position: absolute;
	left: 10%;
	bottom: 20px;
	z-index: 999;
	text-align: center;
}
.nav .i{
    
    
	width: 30px;
	height: 30px;
	display: inline-block;
	cursor: pointer;
	background-color: #aaa;
	text-align: center;
	border-radius: 50%;
	transform: scale(.48);
	transition: all .5s;
}
.nav .i_current{
    
    
	background-color: blue;
	transform:scale(1);
}

猜你喜欢

转载自blog.csdn.net/weixin_43443341/article/details/127211712