在前面我们讲解了一个使用纯CSS制作3D百叶窗效果,今天我们要来制作一个类似名片盒的3D翻页图片画廊。在这个效果中,我们将使用一个HTML5 range
输入框元素来控制图片画廊的前后翻页。这个range
元素使用javascript来控制。最终插件的理论上在不改变代码的情况下可以接受4-20张图片。
HTML结构
这个3D翻页图片画廊的HTML结构很简单,使用一个class为#imgdex
的<div>
来作为包裹容器,里面可以放置多个<figure>
,每个<figure>
是一幅图片,里面使用<figcaption>
来作为图片的标题。
<div id="imgdex"> <figure> <img src="arabic-eyes.jpg" alt="Bedouin headress"> <figcaption>Bedouin</figcaption> </figure> <figure> <img src="blue-green-eyes.jpg" alt="Blue-green-eyes"> <figcaption>Blue-green</figcaption> </figure> <figure> <img src="fake-eyelashes.jpg" alt="Fake eyelashes"> <figcaption>Dramatic Fake</figcaption> </figure> <figure> <img src="snow-queen.jpg" alt="A girl in heavy snow"> <figcaption>Snow</figcaption> </figure> </div>
CSS样式
CSS代码页非常简单,注意下面的代码没有使用厂商的前缀:
#imgdex { position: relative; perspective: 4000px; transform-style: preserve-3d; padding-top: 58%; } #imgdex figure, #imgdex figure figcaption { position: absolute; transition: 1s ease-in-out; } #imgdex figure { top: 0; left: 120px; transform-origin: left bottom; width: 70%; } #imgdex figure figcaption { bottom: 0; font-size: 1.2rem; left: -8rem; opacity: 0; } #imgdex figure:last-of-type{ transform: rotateX(5deg); box-shadow: 0px 0px 200px rgba(0,0,0,0.5); }
在div#imgdex
设置perspective
来控制图片的3D效果,除了最后一个意外的所有<figure>
元素都通过javascript绕它们的底边向前旋转,直到形成一个水平面。最后一个<figure>
元素通过box-shadow
给它提供一个阴影效果。最后一个<figure>
元素是不会移动的。
在div#imgdex
元素下面是一个range
输入框元素:
<input type="range" min="1" onfocus="this.oldvalue = this.value;" oninput="updateImage(this);this.oldvalue = this.value;" id="ranger">
JAVASCRIPT
当range
元素被移动的时候,updateImage()
方法被调用,并传递它的当前值和前一个值。
在使用滑块之前,我们要给它提供一个上限值,这个值默认和图片的数量相等。
var imgdex = document.getElementById('imgdex'), figs = imgdex.querySelectorAll('figure'), imgcount = figs.length; ranger.max = imgcount; ranger.value = imgcount;
最后,我们需要根据滑块的位置来进行相应图片翻页。
for (var i=0; i <(imgcount-1); i++) { var rotation = parseFloat(-92 + "." + (imgcount - i)); figs[i].style.webkitTransform = 'rotateX(' + rotation + 'deg)'; figs[i].style.transform = 'rotateX(' + rotation + 'deg)'; } document.querySelector('#imgdex figure:last-child figcaption').style.opacity = 1; function updateImage(slider) { var currentimg = document.querySelector('#imgdex figure:nth-child('+slider.value+')'); if (slider.oldvalue !== undefined) { var oldimg = document.querySelector('#imgdex figure:nth-child('+(slider.oldvalue)+')'); } else { slider.oldvalue = imgcount; var oldimg = document.querySelector('#imgdex figure:nth-child('+(slider.oldvalue)+')'); } if (slider.value < slider.oldvalue) { currentimg.style.webkitTransform = 'rotateX('+slider.value+'deg)'; currentimg.style.transform = 'rotateX('+slider.value+'deg)'; } if (slider.value > slider.oldvalue) { var rotation = parseFloat(-92 + "." + (imgcount - slider.value)); oldimg.style.webkitTransform = 'rotateX(' + rotation + 'deg)'; oldimg.style.transform = 'rotateX(' + rotation + 'deg)'; } if (slider.value !== slider.oldvalue) { currentimg.querySelector('figcaption').style.opacity = 1; oldimg.querySelector('figcaption').style.opacity = 0; } }
上面的代码有点复杂:
- 首先,它将除了第一个以外的所有
<figure>
元素都向前旋转,每张图片的旋转度数都依次降低,这样可以使图片有一些层次感。由于Safari浏览器仍然需要浏览器前缀来支持transformation,所以代码中也做了相应的添加。 - 接下来是滑块的当前值,这个值确定当前显示那副图片。还有就是单位图片标题的正确位置和可见性。
这个HTML5 3D翻页图片画廊还是一个开放中的版本,也许会存在一些问题,但我们也已从中学习到许多东西,希望对你有所帮助。