在一些运营活动中,为了增加用户参与的趣味性,会在随机的事件中使用卡牌翻转的效果,如下👇
初始 | 翻转中 | 完成 |
---|---|---|
![]() |
![]() |
![]() |
👌,下面,我们就来实现这个效果。
实现
我们有下面的 HTML
骨架:
html
<div class="flip">
<div class="flip-inner">
<div class="flip-inner-front">
<div class="flip-inner-front-text">Front Side</div>
</div>
<div class="flip-inner-back">
<div class="flip-inner-back-text">Back Side</div>
</div>
</div>
</div>
我们设定了前面和后面元素,并用下面的 scss
样式进行润色:
scss
.flip {
width: 300px;
height: 200px;
margin: 0 auto;
&-inner {
position: relative;
width: 100%;
height: 100%;
&-front, &-back {
width: 100%;
height: 100%;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
}
&-front {
background-color: #BBBBBB;
z-index: 2;
}
&-back {
background: #444444;
transform: rotateY(180deg);
z-index: 1;
}
}
}
在上面,我们设定了正面和背面两个 DIV
,并用绝对定位来重叠这两个 DIV
,并使用 zIndex
来做层级的区分。并对背面的 DIV
做 Y
轴的 180 度的旋转。
因为,我们是模拟空间 3d
效果,还需要更改下👇
scss
.flip {
perspective: 1000px;
transform: rotateY(45deg);
&-inner {
transform-style: perserve-3d;
transform: rotateY(45deg);
}
}
这里我们设定了旋转 45
度。并且通过 perspective
指定了观察者与 Z=0
平面的距离,使其具有三维位置变换的元素产生透视效果。然后,我们通过 transform-style
为 perserve-3d
设置元素的子元素位于 3D
空间中。
这里的效果如下所示👇

嗯~
接下来,我们就可以实现下动画效果了。
我们通过点击事件,添加翻转的类 flipped
:
html
<div class="flip" onclick="this.classList.toggle('flipped')">
<!--其他的内容-->
</div>
然后,我们在 scss
文件中添加下面的内容:
scss
.flip {
&-inner {
transition: transform 1.5s;
&-front, &-back {
backface-visibility: hidden; // backface-visibility 指定当前元素背面朝向观察者时是否可见
}
}
&.flipped &-inner {
transform: rotateY(540deg);
}
}
注意:这里的
&.flipped &-inner
别写成&.flipped, &-inner
。它们是两种不同的意思。
上面,我们通过 transition
来定义 transform
的动画。这里是在 1.5s
内将旋转到 450deg
。
当我们点击 flip
这个类元素的时候,就会切换到 .flip.flipped
类上,就会触发翻转到背面的动效。
嗯~这就是我们想要的效果。
那么,我们是否对翻牌增加前置的操作呢?比如 - 随机选牌子👇
这里我们假设了 6
张牌:
react
render (
<div className="container">
{
[1,2,3,4,5,6].map((item: number, index: number) => {
return <div key={index} className="container-item">other content</div>
})
}
</div>
)
然后,我们让选中效果从 0 ~ 5
循环进行展示:
typescript
const [activeIndex, setActiveIndex] = useState<number>(0);
useEffect(() => {
const timer = setInterval(() => {
setActiveIndex((activeIndex) => (activeIndex + 1) % 6); // 0-5循环【当然,我们也可以随机获取 Math.floor(Math.random()*6)】
}, 200);
return () => {
timer && clearInterval(timer);
}
},[])
当随机翻牌的动效播放结束之后,然后触发翻牌的旋转动画出牌结果。
ps: 使用关键帧 @keyframe 也不错
当然,读者可以发动下自己的小脑袋,想想还有什么趣味的操作,增加用户在页面上的停留时间🤔