实现效果
React代码
import React,{FC,useEffect,useState} from 'react'
import styles from './index.less'
import title from '../../img/cardRolling/cardRollTitle.png'
const cardRolling:FC= ()=>{
const cardArr = [{key:1},{key:2},{key:3},{key:4}]
const [clickCard,setCard] = useState(0) //点击了哪张卡片
const [backVisible, setBackVisible] = useState(false); //是否显示背面
const [backRollVisible, setbackRollVisible] = useState(false); //是否显示背面翻转动画
useEffect(()=>{
/*
rem单位
rem是css中的一个尺寸单位,和px、%,em(相对于父元素的字体大小)单位一样都是设置大小
rem:html字体大小的多少倍
用法:
设置rem大小:
方式一
document.documentElement.style.fontSize=(document.documentElement.clientWidth/750)*100+'px';
方式二:
document.documentElement.style.fontSize='10vw';
即1rem等于屏幕宽度的10分之一,若宽为375px,则1rem=37.5px;
750px是当前流行美工稿大小;
所以根据用法可得:
保证在750px大小的设备当中,1 rem=100px;
在350px大小的设备中,1 rem=50px;
*/
document.documentElement.style.fontSize=(document.documentElement.clientWidth/750)*100+'px';
},[])
// 翻牌
const overturn = (cardId:number)=>{
// 已经翻牌 不可以再点击翻牌
if(clickCard!==0) return
setCard(cardId)
// 正面翻转到90度消失,设置成true 背面从90度翻转到0
setTimeout(()=>{
setbackRollVisible(true) //显示背面翻转动画
setBackVisible(true) //显示背面
},800)
}
return(
<div className={styles.BG}>
<img src={title} className={styles.title}/>
<div className={styles.cards}>
{
cardArr.map((item)=>{
return(
<>
{
clickCard!==item.key?
<div
key={item.key}
className={`${styles.card}`}
onClick = {()=>overturn(item.key)}
/>:
<>
{
!backVisible?
<div
key={item.key}
className={`${styles.card} ${clickCard===item.key?styles.cardRoll:null}`}
onClick = {()=>overturn(item.key)}
>
</div>:
<div
key={item.key}
className={`${!backRollVisible?styles.cardBack:styles.cardBackRoll}`}
>
<span className={styles.text}>翻牌背面显示内容</span>
</div>
}
</>
}
</>
)
})
}
</div>
<div onClick={()=>{setBackVisible(false);setCard(0)}}>重新翻牌</div>
</div>
)
}
export default cardRolling
css代码
.BG{
width: 6.6rem;
background-color: #FEE6D5;
border-radius: 0.5rem;
border:0.4em #E6B28C solid;
text-align: center;
.title{
width: 3.69rem;
margin-top: -0.2rem;
text-align: center;
}
.text{
font-size: 0.2rem;
color: #532B05;
font-weight: 400;
line-height: 3.08rem;
}
.cards{
margin: 0.7rem 0;
display: flex;
justify-content: center;
align-items: center;
flex-wrap: wrap; //flex布局自动换行
transform-style: preserve-3d
}
// 正面
.card{
background-image: url(../../img/cardRolling/cardBG.png);
background-repeat: no-repeat;
background-size: cover;
display: inline-block;
width: 2.3rem;
height: 3.08rem;
margin: 0.2rem;
}
// 正面翻转
.cardRoll{
background-image: url(../../img/cardRolling/cardBG.png);
background-repeat: no-repeat;
background-size: cover;
display: inline-block;
width: 2.3rem;
height: 3.08rem;
margin: 0 0.2rem;
transform: rotateY(90deg) ;
transition: linear;
transition-duration: 0.7s;
}
// 背面
.cardBack{
background-image: url(../../img/cardRolling/cardBG2.png);
background-repeat: no-repeat;
background-size: cover;
display: inline-block;
width: 2.3rem;
height: 3.08rem;
margin: 0.2rem;
}
// 背面翻转
.cardBackRoll{
background-image: url(../../img/cardRolling/cardBG2.png);
background-repeat: no-repeat;
background-size: cover;
display: inline-block;
width: 2.3rem;
height: 3.08rem;
margin: 0.2rem;
transform: rotateY(0deg) ;
transition: linear;
transition-duration: 0.7s;
}
}
总结
主要是使用了css的transform属性,操纵y轴上的旋转来实现翻牌效果
1、点击卡片时记录卡片id
2、将点击的卡片div赋值正面翻转的类
className={`${styles.card} ${clickCard===item.key?styles.cardRoll:null}`}
3、当正面卡片选择90度消失之后,再设置背面的翻转
// 正面翻转到90度消失,设置成true 背面从90度翻转到0
setTimeout(()=>{
setbackRollVisible(true) //显示背面翻转动画
setBackVisible(true) //显示背面
},800)
<div
key={item.key}
className={`${!backRollVisible?styles.cardBack:styles.cardBackRoll}`}
>
<span className={styles.text}>翻牌背面显示内容</span>
</div>
4、完成翻转 显示背面结果
5、为什么需要backRollVisible这个字段?
答:为了控制用户抽奖完毕之后再次打开页面的结果回显,这个时候是不需要翻转动画的,这个时候我们只需要把backRollVisible设置成false,backVisible设置成true