在前面我们讲解了一个使用纯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翻页图片画廊还是一个开放中的版本,也许会存在一些问题,但我们也已从中学习到许多东西,希望对你有所帮助。