React九宫格抽奖
思路: 一、.九宫格,8个奖项,中心1个抽奖按钮。 二、转的方向是顺时针,也就是说转的顺序如图:0-1-2-3-4-5-6-7。
三、如何排版? ? ? ? ?优点:样式布局简单点; 缺点:数据和旋转的顺序不一致,可以处理数据改变数据的排序,后续获得奖项,转到对应的位置,又需要处理一次数据。
优点:把数据通过定位的方式,让数据和旋转顺序一致,数据操作简单。 刚开始选择的flex布局,后来后端交互的时候,只返回中奖奖品名称。需要做过多的数据处理。最终选择了绝对定位。 四、设计一个定时器,接受3个参数: position-起始序号, result-结果序号, speed-速度。 1.当用户点击抽奖,设置0位置开始,设置一个大于30s的result,设置一个speed速度,开启定时器,请求抽奖接口,返回结果后,清除定时器,并获取此时转盘停止的奖项序号。 2.再次设置一个慢一点的速度,开启定时器,传入起始位置,算出停止位置距离0位置的补差个数,result=补差个数+中奖结果的序号,设置一个慢一点speed速度,再把他转完。 ? 代码 一、请求后端接口,获取8个项品,处理数据,然后css去定位九宫格 // 定义timer定时器,按钮状态可点击 constructor(props) { super(props); this.timer; this.state = { dataSource: [],isDisabled: false,prizeName: ‘‘ } } // componentWillReceiveProps生命周期中处理 if(data){ data.map((v,i)=>{ Object.assign(v,{ isActive: false,index: ‘s1‘,classText: ‘p1‘ }); }) data[0].isActive = true; this.setState({ data }); } // render中 return() <div className="draw-section"> {dataSource && dataSource.map((v,i) => ( <div key={v.id} className={v.isActive ? `draw-item active p${i}` : `draw-item p${i}`} > <img src={v.imgUrl} alt="" /> <p className=‘item-prize-name‘>{v.prizeName}</p> </div> )) } <div className="draw-item draw-btn"> <input type="button" className="btn" onClick={this.handleClick} disabled={this.state.isDisabled} /> <p className=‘draw-times‘>抽奖次数*{this.state.total}</p> </div> </div> ? 二、点击抽奖,执行handleClick方法。 this.start(0,999999,50); // 开启定时器,转盘转动 this.draw(); // 发起一个请求,获取奖品 start = (position,result,speed) => { // position-起始序号 result-结果序号 speed-速度 this.round = 0; // 总次数 this.active = position; // 起始位置 const { dataSource } = this.state; // console.log(‘dataSource‘,dataSource); this.timer = setInterval(() => { if (this.round < result) { if (this.active === 7) { this.active = 0; } else { this.active += 1; } this.round += 1; for (let i = 0,l = dataSource.length; i < l; i += 1) { if (i === this.active) { dataSource[i].isActive = true; } else { dataSource[i].isActive = false; } } this.setState({ dataSource,activeIndex: this.active }); // console.log(‘timer‘,this.active); } else { setTimeout(() => { this.setState({ prizeModal: true,isDisabled: false }); },1000); clearInterval(this.timer); } },speed); } ? 三、接口返回结果后,在componentWillReceiveProps生命周期中,延时2s清除第一个定时器,接着开启新的定时器转到中奖位置。 setTimeout(() => { const { activeIndex } = this.state; // 清除定时器 clearInterval(this.timer); // 获取清除上一次定时器时停在的activeIndex为开启下一个定时器起始位置,并补上未转一整圈的个数, this.start(activeIndex,(8 - activeIndex) + resultIndex,400); },2000); 四、其他需要考虑的,如果接口30s超时,转盘会一直转,返回异常则清除定时器。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |