临近618,公司产品需要做促销活动,产品经理提出新需求,要做一个转盘抽奖的功能。接到这个需求时,我的内心其实是拒绝的,奈何,身不由己。做吧!!!

UI效果图如下:

接到这个任务时,原本是想找个现有的插件去实现,由于需要同时开发h5和微信小程序两个端,苦苦寻觅,终找不到合适的,罢了罢了,还是自己动手,丰衣足食吧!

实现原理: 通过css3的 transitiontransform 两个属性

具体实现步骤:

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实现转盘抽奖功能相关推荐

  1. 微信转发抽奖+php,jQuery+PHP实现微信转盘抽奖功能的方法

    本文实例讲述了jQuery+PHP实现微信转盘抽奖功能的方法.分享给大家供大家参考,具体如下: 本文结合实例将使用jQuery和PHP来实现转盘抽奖程序. 准备工作 首先要准备素材,抽奖的界面用到两张 ...

  2. PHP做大转盘抽奖的思路,jQuery+PHP实现微信转盘抽奖功能的方法

    本文实例讲述了jQuery+PHP实现微信转盘抽奖功能的方法.分享给大家供大家参考,具体如下: 本文结合实例将使用jQuery和PHP来实现转盘抽奖程序. 准备工作 首先要准备素材,抽奖的界面用到两张 ...

  3. 转盘抽奖hTML CSS jquery,jquery转盘抽奖功能实现

    一.用到的素材 二.代码如下,重点是js部分 jQuery九宫格大转盘抽奖 #lottery{width:570px;height:510px;margin:0px auto;border:4px s ...

  4. PHP 实现积分兑换和大转盘抽奖功能,防超卖

    目录 前情提要 如何不发生超卖现象? 代码如何实现 Redis 锁的实现(悲观锁) 结论 前情提要 前段时间帮客户做了一个线上会议网站,网站实际运营 2 个多月,正常参会用户注册量大概有1万多. 网站 ...

  5. vue3 - 网页大转盘抽奖功能,支持后端接口确定最终奖品,可自定义轮盘宽高、颜色、字号、按钮等等(超详细的示例代码及注释开箱即用,稍微改改就能应用到你的项目中)

    效果图 网上的 vue3 教程非常少,找了几篇代码太乱根本无法改造和使用.. 如下图所示,你可以自己 DIY 转盘的大小位置及样式,中奖的商品由后端接口控制, 代码干净只有核心的功能,注释超级详细新手 ...

  6. 数据库表设计——转盘抽奖功能

    一.基本需求 1. 不同的活动有不同的奖项配置: 2. 奖项类型大概有红包,实物,再来一次,积分等等: 3. 在不同的活动中,每个用户每天有多少次的抽奖机会: 二.需求分析 1. 我们可以把每个活动抽 ...

  7. React实现大转盘抽奖效果

    React利用canvas实现大转盘抽奖效果,效果如下: 大转盘效果 主要代码: const drawImg = (x, y, r, num, ctx, index, img) => {ctx. ...

  8. php ajax 概率 转盘,php+jquery实现转盘抽奖 概率可任意调

    转盘抽奖,炫丽的一般是flash做的.不懂flash而又不需要那么炫丽,可以简单的通过jquery来实现.网上教程有很多,跟着做了一下,也贴出来吧.要实现转盘抽奖,有两个关键点,一是让转盘或指针转起来 ...

  9. 原生JS实现简易转盘抽奖

    我爱撸码,撸码使我感到快乐. 大家好,我是Counter. 本章带大家来简单的了解下原生JS实现转盘抽奖. 因为主要涉及到JS,在这里HTML和CSS起到的功能就没有那么重要, 因此,没有过多的阐述H ...

最新文章

  1. spark 算子例子_10年大数据架构师,用一文带你玩转Spark计算框架,你能读懂吗?...
  2. leetcode面试题 08.03. 魔术索引(二分)
  3. H5页面移动端双击屏幕禁止页面放大
  4. 数字化转型知识方法系列之五:数字化转型战略
  5. AE安装部署以及监测ArcEngine runtime 9.3是否安装
  6. 奔图龙芯计算机认证报告,龙芯3A 1500 3U VPX加固计算机
  7. OpenGL和OpenCV的区别
  8. MyBatis框架的使用及源码分析(三) 配置篇 Configuration
  9. Download and Install R and RStudio for win10
  10. Mac 上Dock中添加“最近打开过的项目”(Recent Applications)
  11. LINUX编译ARM64/AARCH64版本的jogamp(gluegen/jogl)注意事项
  12. 计算机网络实验(二)2交换机的基本配置与管理
  13. R语言快速画出ROC曲线和算出可信区间和p值
  14. Python+OpenCV实现实时视频3D换脸
  15. 手把手教你打造一个VIM-IDE
  16. 支付宝AR红包引出Python中的PIL小试
  17. Modem2G/3G/4G/5G:完整收录,2020最新MCC、MNC、运营商对照表,全球运营商MCCMNC查询列表
  18. 受迫阻尼 matlab 仿真,有阻尼受迫振动系统的计算机仿真分析
  19. c语言c11标准 pdf,C语言新标准C11
  20. 计算机PAD网络是什么,iPad平板电脑的WLAN与Cellular版有什么区别【详细介绍】

热门文章

  1. 高精度倾角传感器的应用
  2. 3D游戏编程设计作业八
  3. 内网渗透——搭建域控制器
  4. sqlserver mysql bigint_sqlserver bigint(20)
  5. 2019届百度秋招笔试题【混战世界】【字符串计数】
  6. Java期末复习题 超级无敌全
  7. excel中查找绝对值最大的方法
  8. 30个优秀的CSS导航菜单和按钮教程
  9. 用了10年开源工具,换了Smartbi后,3分钟搞定一份报表
  10. 我妈这是怎么了!谁来帮帮我。