展示页效果
学习妙味课堂的展示页效果
效果预览:展示页
知识点预备:
【1】transform-style属性
transform-style属性指定了它的子元素看起来是存在3D空间中,还是存在2D空间中,如果存在2D空间中,则它的子元素不能存在3D中。
注意:因为该属性不会被(自动)继承,所以必须为元素所有非叶后代节点设置该属性。
语法:transform-style: flat | preserve-3d
preserve-3d
指定子元素定位在三维空间内
flat
指定子元素位于此元素所在平面内。
【2】perspective属性
MDN官方文档说明:
perspective
属性指定了观察者与z=0平面的距离,使具有三维位置变换的元素产生透视效果。z>0的三维元素比正常大,而z<0时则比正常小,大小程度由该属性的值决定。
举栗子:
1 <style> 2 #wrap{ 3 4 position: relative; 5 } 6 #wrap img{ 7 position: absolute; 8 top: 100px; 9 left: 400px; 10 transform: rotateY(40deg); 11 } 12 </style> 13 </head> 14 <body> 15 <div id="wrap"> 16 <img src="img/0.png" /> 17 18 </div> 19 20 21 </body>
效果:
这里我们没有设置perspective属性看不到什么变化,那我们将这个属性加上看看有什么变化
代码:
1 <style> 2 #wrap{ 3 perspective: 1200px; 4 position: relative; 5 } 6 #wrap img{ 7 position: absolute; 8 top: 100px; 9 left: 400px; 10 transform: rotateY(40deg); 11 } 12 </style> 13 </head> 14 <body> 15 <div id="wrap"> 16 <img src="img/0.png" /> 17 18 </div> 19 </body>
效果:
可以看到有很大的变化。难道第一张图片没有旋转吗?不,它旋转了,只是离得我们太远看不到而已。设置perspective这个属性就是将镜头拉到一定距离。
【3】transition属性
语法:transition: property duration timing-function delay;
详细解析:留个位置(这两天会为transition属性单独写一个博客)
我们这里用到了 duration 和 timing-function 。
1 transition: .7s ease-in-out;
意思是这个元素的的动画花费0.7s,并且慢速开始,慢速结束。
准备工作完毕,开始正式写代码
第一步
写基本的结构和样式,直接看代码
1 <style> 2 body{ 3 margin: 0; 4 background-color: #999; 5 } 6 #wrap{ 7 height: 500px; 8 background: url(img/bg.png) no-repeat center; 9 background-size: 1800px 500px; 10 position: relative; 11 transform-style: preserve-3d; 12 perspective: 800px; 13 margin-top: 100px; 14 } 15 img{ 16 border: none; 17 /*垂直对齐方式*/ 18 vertical-align: top; 19 } 20 #wrap img{ 21 width: 300px; 22 height: 200px; 23 position: absolute; 24 left: 50%; 25 top: 50%; 26 margin-left: -150px; 27 margin-top: -100px; 28 transition: .7s ease-in-out; 29 } 30 </style> 31 </head> 32 <body> 33 <div id="wrap"> 34 <img src = "img/0.png"> 35 <img src = "img/1.png"> 36 <img src = "img/2.png"> 37 <img src = "img/3.png"> 38 <img src = "img/4.png"> 39 <img src = "img/5.png"> 40 <img src = "img/6.png"> 41 </div> 42 </body>
第二步:
写tab()函数,这个函数的作用接受一个n值,并根据这个n值来设置每个图片的位置和样式。
先来看看设置的变量
1 var imgs = document.getElementsByTagName('img'); 2 //默认的最中间的图片的序号 3 var now = 3; 4 //你想要看的图片的序号,即鼠标点击的图片序号 5 var target = 0; 6 //开关,设置它是为了让用户点击一个图片后要等到这个动画效果完成后,才可以继续点击 7 var onoff = true;
tab()函数
1 function tab(n){ 2 //除了最中间的每边都有三个div,他们都是对称的,所以只循环三次 3 for(var i = 0;i < 3;i++){ 4 5 var Left = n - 1 - i; 6 // 如果是这样的情况 4 5 6 0 1 2 3 7 if(Left < 0){ 8 Left = Left + 7; 9 } 10 //给左边的div设置位置 11 imgs[Left].style.transform = "translateX("+(-150*(i+1))+"px) translateZ("+(200-i*100)+"px) rotateY(30deg)" 12 13 var Right = n + 1 + i; 14 // 如果是这样的情况 3 4 5 6 0 1 2 15 if(Right > 6){ 16 Right = Right - 7; 17 } 18 //给右边的div设置位置 19 imgs[Right].style.transform = "translateX("+(150*(i+1))+"px) translateZ("+(200-i*100)+"px) rotateY(-30deg)" 20 } 21 //最中间的div设置它的Z轴距离,使它到最前面 22 imgs[n].style.transform = "translateZ(300px)"; 23 }
代码不难就是修改一些CSS3中的属性
第三步
当你点击一个图片时,这个图片运动到到最中间的位置有两种方法:goNext()和goPrev()
1 //向后切换图片 2 function goNext(){ 3 now ++; 4 //如果中间的图片时最后一张,它的下一张是第一张 5 if(now > 6){ 6 now =0; 7 } 8 tab(now); 9 //切换完成,结束函数 10 if(now == target){ 11 //切换完成,用户可以点击图片 12 onoff = true; 13 return; 14 } 15 //如果没有到点击的图片时,继续向后走 16 setTimeout(function(){ 17 goNext(); 18 },1000); 19 } 20 21 //向前切换图片 22 function goPrev(){ 23 now --; 24 //如果中间的图片是第一张,它的上一张是第六张 25 if(now < 0){ 26 now = 6; 27 } 28 tab(now); 29 //切换完成,结束函数 30 if(now == target){ 31 //切换完成,用户可以点击图片 32 onoff = true; 33 return; 34 } 35 //如果没有到点击的图片时,继续向前走 36 setTimeout(function(){ 37 goPrev(); 38 },1000); 39 }
第四步
写if语句来判断被点击的图片用那种方式到最中间的位置
1 for(var i = 0;i < imgs.length;i++){ 2 imgs[i].index = i; 3 imgs[i].onclick = function(){ 4 if(!onoff){ 5 return; 6 } 7 onoff = false; 8 target = this.index; 9 if(target > now){ 10 if(target - now <= 3){ 11 goNext(); 12 } 13 else{ 14 goPrev(); 15 } 16 } 17 if(target < now){ 18 if(now - target <= 3){ 19 goPrev(); 20 }else{ 21 goNext(); 22 } 23 } 24 25 } 26 }
第五步
第五步应该是写开关,因为第四步基本效果已经完成了。但是还是有一个小bug,就是在图片切换过程中如果继续点击图片,整个图片的布局会变。所以引入开关,不让用户在动画还未完成前点击。
总结:难度不大,对CSS3中的属性不熟悉。对如何选择goNext()或者goPrve()绕了一会,最后在纸上画出各种情况后才懂。
源码:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style> 7 body{ 8 margin: 0; 9 background-color: #999; 10 } 11 #wrap{ 12 height: 500px; 13 background: url(img/bg.png) no-repeat center; 14 background-size: 1800px 500px; 15 position: relative; 16 transform-style: preserve-3d; 17 perspective: 800px; 18 margin-top: 100px; 19 } 20 img{ 21 border: none; 22 /*垂直对齐方式*/ 23 vertical-align: top; 24 } 25 #wrap img{ 26 width: 300px; 27 height: 200px; 28 position: absolute; 29 left: 50%; 30 top: 50%; 31 margin-left: -150px; 32 margin-top: -100px; 33 transition: .7s ease-in-out; 34 } 35 </style> 36 </head> 37 <body> 38 <div id="wrap"> 39 <img src = "img/0.png"> 40 <img src = "img/1.png"> 41 <img src = "img/2.png"> 42 <img src = "img/3.png"> 43 <img src = "img/4.png"> 44 <img src = "img/5.png"> 45 <img src = "img/6.png"> 46 </div> 47 <script> 48 var imgs = document.getElementsByTagName('img'); 49 //默认的最中间的图片的序号 50 var now = 3; 51 //你想要看的图片的序号,即鼠标点击的图片序号 52 var target = 0; 53 //开关,设置它是为了让用户点击一个图片后要等到这个动画效果完成后,才可以继续点击 54 var onoff = true; 55 56 setTimeout(function(){ 57 tab(now); 58 },100); 59 60 61 for(var i = 0;i < imgs.length;i++){ 62 imgs[i].index = i; 63 imgs[i].onclick = function(){ 64 if(!onoff){ 65 return; 66 } 67 onoff = false; 68 target = this.index; 69 if(target > now){ 70 if(target - now <= 3){ 71 goNext(); 72 } 73 else{ 74 goPrev(); 75 } 76 } 77 if(target < now){ 78 if(now - target <= 3){ 79 goPrev(); 80 }else{ 81 goNext(); 82 } 83 } 84 85 } 86 } 87 88 // 0 1 2 3 4 5 6 89 function tab(n){ 90 //除了最中间的每边都有三个div,他们都是对称的,所以只循环三次 91 for(var i = 0;i < 3;i++){ 92 93 var Left = n - 1 - i; 94 // 4 5 6 0 1 2 3 95 if(Left < 0){ 96 Left = Left + 7; 97 } 98 //给左边的div设置位置 99 imgs[Left].style.transform = "translateX("+(-150*(i+1))+"px) translateZ("+(200-i*100)+"px) rotateY(30deg)" 100 101 var Right = n + 1 + i; 102 // 3 4 5 6 0 1 2 103 if(Right > 6){ 104 Right = Right - 7; 105 } 106 //给右边的div设置位置 107 imgs[Right].style.transform = "translateX("+(150*(i+1))+"px) translateZ("+(200-i*100)+"px) rotateY(-30deg)" 108 } 109 //最中间的div设置它的Z轴距离,使它到最前面 110 imgs[n].style.transform = "translateZ(300px)"; 111 } 112 113 //向后切换图片 114 function goNext(){ 115 now ++; 116 //中间的图片时最后一张,它的下一张是第一张 117 if(now > 6){ 118 now =0; 119 } 120 tab(now); 121 //切换完成,结束函数 122 if(now == target){ 123 //切换完成,用户可以点击图片 124 onoff = true; 125 return; 126 } 127 //如果没有到想看的图片时,继续向后走 128 setTimeout(function(){ 129 goNext(); 130 },1000); 131 } 132 133 //向前切换图片 134 function goPrev(){ 135 now --; 136 //中间的图片是第一张,它的上一张是第六张 137 if(now < 0){ 138 now = 6; 139 } 140 tab(now); 141 //切换完成,结束函数 142 if(now == target){ 143 //切换完成,用户可以点击图片 144 onoff = true; 145 return; 146 } 147 //如果没有到想看的图片时,继续向前走 148 setTimeout(function(){ 149 goPrev(); 150 },1000); 151 } 152 </script> 153 </body> 154 </html>