- A+
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
翻转图像是在视觉上比较两个不同图像的常用方法。单击其中一个将翻转它,并显示另一个图像。
布局
布局结构如下:
<div class="flipping-images"> <div class="flipping-images__inner"> <div class="flipping-images__side flipping-images__side--front"> <!-- The image shown on the front --> <img class="flipping-images__img" src="..." /> </div> <div class="flipping-images__side flipping-images__side--back"> <!-- The image shown on the back --> <img class="flipping-images__img" src="..." /> </div> </div> </div>
它有正面和背面两面,放置在内部容器内。我们希望它们彼此重叠。最好的方法是使用容器 relative
的样式,并绝对定位它们。
.flipping-images__inner { /* Take full size of the root element */ height: 100%; width: 100%; position: relative; } .flipping-images__side { /* Take full size of the inner container */ height: 100%; width: 100%; /* Absolute position */ position: absolute; top: 0; left: 0; }
最初,正面显示在背面的上部。用户在单击正面之前不会看到背面。这就是 z-index
该属性派上用场的地方。
.flipping-images__side--back { z-index: 1; } .flipping-images__side--front { z-index: 2; }
图像必须适合其侧面。在不显式设置 width 和 height 属性的情况下,我们可以使用 object-fit
属性将图像完美地放入每一侧:
.flipping-images__img { /* Take the full height */ height: 100%; /* But don't exceed the side's width */ max-width: 100%; /* Fit within each side */ object-fit: cover; }
内部居中
我们希望在根元素的中心显示内部容器。使用三个 CSS flexbox 属性的组合将使我们能够做到这一点:
.flipping-images { /* Center the content */ align-items: center; display: flex; justify-content: center; }
此外,我们还需要设置内容器的宽度。它必须与图像的宽度相同。我们可以处理其中一个图像 load
的事件,然后确定其宽度:
const handleLoad = (e) => { const imageEle = e.target; // Get the image's width const width = imageEle.getBoundingClientRect().width; // Assume `innerEle` represents the inner container innerEle.style.width = `${width}px`; }; // Assume `containerEle` represents the root element containerEle.querySelector('.flipping-images__img').addEventListener('load', handleLoad);
动画
为了获取您在本文开头看到的动画,我们需要在用户单击内部容器时旋转它。我们创建了一个翻转变体,将内部容器在垂直方向上旋转 180 度:
.flipping-images__inner { transition: transform 800ms; } .flipping-images__inner--flip { transform: rotateY(180deg); }
当用户单击内部容器时,我们会切换翻转变体:
// Assume `innerEle` represents the inner container innerEle.addEventListener('click', () => { innerEle.classList.toggle('flipping-images__inner--flip'); });
但是,结果是实际上只有第一个图像被旋转。背面的第二张图像仍处于隐藏状态。为了用背面替换正面,我们需要更多额外的样式:
.flipping-images__inner { transform-style: preserve-3d; } .flipping-images__side { backface-visibility: hidden; }
这两个声明都是必需的。否则,当正面旋转时,无法看到背面。最后,由于我们旋转了内部容器,导致背面也旋转了。因此,我们必须反转旋转:
.flipping-images__side--back { transform: rotateY(-180deg); }
3D动画
到目前为止,图像在内部容器内翻转。这种 perspective
将使我们有能力使翻转看起来像 3D 动画。
.flipping-images { perspective: 1000px; }
如果 perspective
的值是内部容器宽度的两倍,则效果最佳。我们可以在上一节中提到的 load
事件处理程序中执行此操作:
const handleLoad = (e) => { const imageEle = e.target; // Get the image's width const width = imageEle.getBoundingClientRect().width; // Assume `containerEle` represents the root element containerEle.style.perspective = `${2 * width}px`; };
水平翻转
我们使用该 rotateY
函数在垂直方向上翻转图像。如果要将翻转方向更改为水平,则可以使用该 rotateX
功能。
.flipping-images__inner--flip { transform: rotateX(180deg); } .flipping-images__side--back { transform: rotateX(-180deg); }