这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
翻转图像是在视觉上比较两个不同图像的常用方法。单击其中一个将翻转它,并显示另一个图像。
布局
布局结构如下:
<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);
}