react实现转盘抽奖功能
临近618,公司产品需要做促销活动,产品经理提出新需求,要做一个转盘抽奖的功能。接到这个需求时,我的内心其实是拒绝的,奈何,身不由己。做吧!!!
UI效果图如下:
接到这个任务时,原本是想找个现有的插件去实现,由于需要同时开发h5和微信小程序两个端,苦苦寻觅,终找不到合适的,罢了罢了,还是自己动手,丰衣足食吧!
实现原理: 通过css3的 transition 和 transform 两个属性
具体实现步骤:
1、首先,我们简单定义一个奖品数组,实际开发中是调后台接口获取奖品,以下是为了方便演示
const giftArr = [{giftName: 'iphone xs'},{giftName: '小米智能音箱'},{giftName: 'ThinkPad X390 LTE版'},{giftName: 'air pods 2'},{giftName: '雷蛇鼠标'}
]
2、如下图划分区域,因为转盘旋转时是顺时针旋转,所以按照下图划分奖品区域,图中序号表示奖品数组每一项的index
3、定义每个奖品的角度区域
const LOTTERY_AREA_DEG = [[1, 59], [61, 119], [121, 179], [181, 239], [241, 299], [301, 359]]
这里我们把60度的整数倍度数给去掉了,是为了防止转到60度,120度这样的度数
4、为了模拟抽中的奖品,我们写个方法随机生成奖品的序号,以及根据奖品序号拿到转盘需要转到的角度
// 生成两个数范围内的随机整数
const randomNum = (minNum, maxNum) => {return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
}
const giftIndex = randomNum(0, 5)
// 随机取对应奖品区域中的一个角度
const targetDegree = randomNum(LOTTERY_AREA_DEG[giftIndex][0], LOTTERY_AREA_DEG[giftIndex][1])
5、下面将是整个功能中最重要也是笔者花了2天时间,写了10几张草稿纸才想出来的,我们如何才能计算下一次转盘转动的角度,而且要精确的使指针指向对应的区域呢?这里,我想多花点时间,多写点字去讲解一下:
假设第一次抽中了奖品 “iphone xs” ,需要转到26°,第二次抽中了 “小米智能音箱”,需要转到82°,这种情况其实很好理解,我们只需用 transform: rotate(26deg) 和 transform: rotate(82deg);
我们再来看另一种情况,假设第一次抽中了奖品 “air pods 2”,对应区域时3,需要转到221°,第二次抽中了 “小米智能音箱” ,对应区域是1,需要转到70°,那这种情况下,继续用 transform: rotate(70deg) 肯定是不行了,如果这样,会出现转盘逆时针转到区域1了,这样显然不是我们想要的结果,这种情况下我们就需要在70°的基础上再转360°,也就是转到430°的位置,才能达到顺时针旋转的效果。
接着上面的情况,第三次,我们抽中了 “iphone xs”,对应区域是0,对应角度40°,我们按照上面的方法,40°比430°小,不能直接使用transform,那我们就给40°加360°,加了一个360°还不够430°,我们再加,加到2个360°后,发现360 * 2 + 40 = 760 > 430,可以,第三次转到730°就可以。
从上面我们可以发现,下一次需要旋转到的角度一定要比上一次的度数要大, 注意:这里的角度是旋转到多少度,而不是旋转了多少度,这是两个不同的概念,笔者之前就是按照旋转了多少度来计算的,结果除了第一次能旋转到对应的区域,后面每一次都不会旋转到对应的区域了
这里我选择的处理方式是用递归的方式去计算下次要转到的角度,代码如下:
let rotateDeg = 0
// 递归计算下次要转到的度数
let i = 0
const _fn = (n = 0) => {if (targetDegree + 360 * n > this.state.startRotateDeg) {rotateDeg = targetDegree + 360 * n} else {i++_fn(i)}
}
_fn()
上面这段代码算是整个功能函数里的核心代码了。
下面附上完整代码:
import React from 'react'
export default class Lottery extends React.Component{constructor(props){super(props)this.state = {startRotateDeg: 0 // 记录上一次转到的角度}}randomNum = (minNum, maxNum) => {return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);}handleClick = () => {const LOTTERY_AREA_DEG = [[1, 59], [61, 119], [121, 179], [181, 239], [241, 299], [301, 359]]const giftIndex = this.randomNum(0, 5)// 随机取对应奖品区域中的一个角度const targetDegree = this.randomNum(LOTTERY_AREA_DEG[giftIndex][0], LOTTERY_AREA_DEG[giftIndex][1])let rotateDeg = 0// 递归计算下次要转到的度数let i = 0const _fn = (n = 0) => {if (targetDegree + 360 * n > this.state.startRotateDeg) {rotateDeg = targetDegree + 360 * n} else {i++_fn(i)}}_fn()// 获取转盘实例const ele = document.getElementById('turntable')// 增加旋转动画ele.style.transition = 'all 6500ms'ele.style.transform = `rotate(${rotateDeg + 360 * 10}deg)` // 乘以10是为了转盘转动的效果this.setState({startRotateDeg: rotateDeg + 360 * 10 // 记录上一次旋转到的角度})}render(){return(<div>{/* 转盘 */}<div className="turntable" id="turntable"></div>{/* 指针 */}<div className="pointer" onClick={this.handleClick}></div></div>)}
}
至此,本文已结束,希望对大家有所帮助!
react实现转盘抽奖功能相关推荐
- 微信转发抽奖+php,jQuery+PHP实现微信转盘抽奖功能的方法
本文实例讲述了jQuery+PHP实现微信转盘抽奖功能的方法.分享给大家供大家参考,具体如下: 本文结合实例将使用jQuery和PHP来实现转盘抽奖程序. 准备工作 首先要准备素材,抽奖的界面用到两张 ...
- PHP做大转盘抽奖的思路,jQuery+PHP实现微信转盘抽奖功能的方法
本文实例讲述了jQuery+PHP实现微信转盘抽奖功能的方法.分享给大家供大家参考,具体如下: 本文结合实例将使用jQuery和PHP来实现转盘抽奖程序. 准备工作 首先要准备素材,抽奖的界面用到两张 ...
- 转盘抽奖hTML CSS jquery,jquery转盘抽奖功能实现
一.用到的素材 二.代码如下,重点是js部分 jQuery九宫格大转盘抽奖 #lottery{width:570px;height:510px;margin:0px auto;border:4px s ...
- PHP 实现积分兑换和大转盘抽奖功能,防超卖
目录 前情提要 如何不发生超卖现象? 代码如何实现 Redis 锁的实现(悲观锁) 结论 前情提要 前段时间帮客户做了一个线上会议网站,网站实际运营 2 个多月,正常参会用户注册量大概有1万多. 网站 ...
- vue3 - 网页大转盘抽奖功能,支持后端接口确定最终奖品,可自定义轮盘宽高、颜色、字号、按钮等等(超详细的示例代码及注释开箱即用,稍微改改就能应用到你的项目中)
效果图 网上的 vue3 教程非常少,找了几篇代码太乱根本无法改造和使用.. 如下图所示,你可以自己 DIY 转盘的大小位置及样式,中奖的商品由后端接口控制, 代码干净只有核心的功能,注释超级详细新手 ...
- 数据库表设计——转盘抽奖功能
一.基本需求 1. 不同的活动有不同的奖项配置: 2. 奖项类型大概有红包,实物,再来一次,积分等等: 3. 在不同的活动中,每个用户每天有多少次的抽奖机会: 二.需求分析 1. 我们可以把每个活动抽 ...
- React实现大转盘抽奖效果
React利用canvas实现大转盘抽奖效果,效果如下: 大转盘效果 主要代码: const drawImg = (x, y, r, num, ctx, index, img) => {ctx. ...
- php ajax 概率 转盘,php+jquery实现转盘抽奖 概率可任意调
转盘抽奖,炫丽的一般是flash做的.不懂flash而又不需要那么炫丽,可以简单的通过jquery来实现.网上教程有很多,跟着做了一下,也贴出来吧.要实现转盘抽奖,有两个关键点,一是让转盘或指针转起来 ...
- 原生JS实现简易转盘抽奖
我爱撸码,撸码使我感到快乐. 大家好,我是Counter. 本章带大家来简单的了解下原生JS实现转盘抽奖. 因为主要涉及到JS,在这里HTML和CSS起到的功能就没有那么重要, 因此,没有过多的阐述H ...
最新文章
- spark 算子例子_10年大数据架构师,用一文带你玩转Spark计算框架,你能读懂吗?...
- leetcode面试题 08.03. 魔术索引(二分)
- H5页面移动端双击屏幕禁止页面放大
- 数字化转型知识方法系列之五:数字化转型战略
- AE安装部署以及监测ArcEngine runtime 9.3是否安装
- 奔图龙芯计算机认证报告,龙芯3A 1500 3U VPX加固计算机
- OpenGL和OpenCV的区别
- MyBatis框架的使用及源码分析(三) 配置篇 Configuration
- Download and Install R and RStudio for win10
- Mac 上Dock中添加“最近打开过的项目”(Recent Applications)
- LINUX编译ARM64/AARCH64版本的jogamp(gluegen/jogl)注意事项
- 计算机网络实验(二)2交换机的基本配置与管理
- R语言快速画出ROC曲线和算出可信区间和p值
- Python+OpenCV实现实时视频3D换脸
- 手把手教你打造一个VIM-IDE
- 支付宝AR红包引出Python中的PIL小试
- Modem2G/3G/4G/5G:完整收录,2020最新MCC、MNC、运营商对照表,全球运营商MCCMNC查询列表
- 受迫阻尼 matlab 仿真,有阻尼受迫振动系统的计算机仿真分析
- c语言c11标准 pdf,C语言新标准C11
- 计算机PAD网络是什么,iPad平板电脑的WLAN与Cellular版有什么区别【详细介绍】