先看效果
代码如下:
父组件:
import React, { Component } from 'react'
import DeomItem from './demo_item.jsx' // 引入子组件
export default class demo extends Component {
constructor(props) {
super(props);
this.state = {
// 九宫格内容list
list: [
{id: 1, name: '1.2%财富券'},
{id: 2, name: '1.0%财富券'},
{id: 3, name: '1.4%财富券'},
{id: 4, name: '1.1%财富券'},
{id: 5, name: '电视'},
{id: 6, name: '冰箱'},
{id: 7, name: '洗衣机'},
{id: 8, name: '手机'},
{id: 9, name: '手机1'},
{id: 10, name: '手机2'},
{id: 11, name: '手机3'},
{id: 12, name: '手机4'}
],
// 被选中的格子的ID
activedId: '',
// 中奖ID
prizeId: null,
// 获得prizeId之后计算出的动画次数
times: 0,
// 当前动画次数
actTimes: 0,
// 是否正在抽奖
isRolling: false
}
}
handleBegin() {
// this.state.isRolling为false的时候才能开始抽,不然会重复抽取,造成无法预知的后果
if (!this.state.isRolling) {
// 点击抽奖之后,我个人做法是将于九宫格有关的状态都还原默认
this.setState({
activedId: '',
prizeId: null,
times: 0,
actTimes: 0,
isRolling: true
}, () => {
// 状态还原之后才能开始真正的抽奖
this.handlePlay()
})
}
}
handlePlay() {
// 中将id,可随机,可自己设定,我这里暂且定为4
let prize = 4
console.log(prize)
this.setState({
prizeId: prize,
activedId: 0
})
// 随机算出一个动画执行的最小次数,这里可以随机变更数值,按自己的需求来
let times = this.state.list.length * Math.floor(Math.random() * 5 + 4)
this.setState({
times: times
})
// 抽奖正式开始
this.begin = setInterval(() => {
let num;
if (this.state.activedId === this.state.prizeId && this.state.actTimes > this.state.times) {
// 符合上述所有条件时才是中奖的时候,两个ID相同并且动画执行的次数大于(或等于也行)设定的最小次数
clearInterval(this.begin)
this.setState({
isRolling: false
})
return
}
// 以下是动画执行时对id的判断
if (this.state.activedId === '') {
num = 0
this.setState({
activedId: num
})
} else {
num = this.state.activedId
if (num === 11) {
num = 0
this.setState({
activedId: num
})
} else {
num = num + 1
this.setState({
activedId: num
})
}
}
this.setState({
actTimes: this.state.actTimes + 1
})
}, 40)
}
render() {
const { list, activedId } = this.state;
return (
<div className="demo">
<div className="start_button" onClick={() => this.handleBegin()}>开始</div>
<div className="one">
<DeomItem content={list[0]} activedId={activedId}></DeomItem>
<DeomItem content={list[1]} activedId={activedId}></DeomItem>
<DeomItem content={list[2]} activedId={activedId}></DeomItem>
<DeomItem content={list[3]} activedId={activedId}></DeomItem>
</div>
<div className="one">
<DeomItem content={list[11]} activedId={activedId}></DeomItem>
<DeomItem content={list[4]} activedId={activedId}></DeomItem>
</div>
<div className="one">
<DeomItem content={list[10]} activedId={activedId}></DeomItem>
<DeomItem content={list[5]} activedId={activedId}></DeomItem>
</div>
<div className="one">
<DeomItem content={list[9]} activedId={activedId}></DeomItem>
<DeomItem content={list[8]} activedId={activedId}></DeomItem>
<DeomItem content={list[7]} activedId={activedId}></DeomItem>
<DeomItem content={list[6]} activedId={activedId}></DeomItem>
</div>
</div>
);
}
}
子组件:
import React, { Component } from 'react'
export default class demoItem extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
const { content, activedId } = this.props;
return (
<div className={activedId === content.id ? 'row_item row_item-active' : 'row_item'} id={`row_item_${content}`}>
{content.name}
</div>
);
}
}
css样式:
我这里用的是scss
@function rem($px){
@return $px * 36 / 7200 + rem;
}
.demo {
height: rem(655);
margin: rem(20);
border: 1px solid #333;
background: #fff;
position: relative;
.start_button {
display: flex;
justify-content: center;
position: absolute;
left: calc(50% - 40px);
top: calc(50% - 20px);
width: rem(150);
height: rem(60);
line-height: rem(60);
text-align: center;
background: aliceblue;
}
.one {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
.row_item {
width: rem(150);
height: rem(150);
line-height: rem(150);
text-align: center;
background: #f0f0f0;
}
.row_item-active {
background: aquamarine;
animation: blink 1s 3;
}
@keyframes blink{
to {
color: transparent;
}
}
}
}