内容简介:额,因为gif压缩了,所以画质有点。。。呵呵,没关系的于是将转盘组件化,具体的需求是:这里主要是两张背景图不断替换,通过定时器,不断替换background形成闪烁的效果.
额,因为gif压缩了,所以画质有点。。。呵呵,没关系的
需求
于是将转盘组件化,具体的需求是:
- 传入一个奖品数组.
- 能够在点击转的按钮时候做一些判断是否可以开转.
- 开转后有一个回调,用于请求奖品返回.
- 转动结束/中奖回调.
- 转动按钮,背景图可配置. 具体props为
params | type | desc |
---|---|---|
image_spin | string | spin button |
background_1 | string | background_1 |
background_2 | string | background_2 |
prizeList | array | [{icon:'imageurl',name:'prize1',id:1},{icon:'imageurl',name:'prize1',id:2}] |
award | object | award should be null first,after request back return an object like prizelist[0] |
canStartRotate | bool | control the turnplate should startRotate |
onTryRotate | func | trigger after click the rotate button,should do some check stuff and if it's ok,set canStartRotate to be true then the turnplate start rotating,meanwhile request for the award and after the request finish,set the award |
rotateFinish | func |
实现思路
转盘外圈的闪烁
这里主要是两张背景图不断替换,通过定时器,不断替换background形成闪烁的效果.
//外面闪闪发光的东东 _outDiscFlash() { const { background_1, background_2 } = this.props; this.outShowImg1 = !this.outShowImg1; if (this.outShowImg1) { this.refs.turnplateBorder.style.backgroundImage = `url(${background_1})`; } else { this.refs.turnplateBorder.style.backgroundImage = `url(${background_2})`; } this._flashTimer = setTimeout(this._outDiscFlash, this.outDiskDiffTimer); } _initFlash() { const { background_1 } = this.props; this.outDiskDiffTimer = 100; this.outShowImg1 = true; this._flashTimer = null; this.refs.turnplateBorder.style.backgroundImage = `url(${background_1})`; } 复制代码
转盘的奖品绘制
1.首先是根据传进来的奖品数组个数,用canvas来画扇形填充。用devicePixelRatio是为了适配手机。
draw() { const { prizeList } = this.props; let rotateDeg = 360 / prizeList.length / 2 + 90, // 扇形回转角度 ctx; const canvas = document.getElementById("canvas"); if (!canvas.getContext) { return; } // 获取绘图上下文 ctx = canvas.getContext("2d"); for (let i = 0; i < prizeList.length; i++) { // 保存当前状态 ctx.save(); // 开始一条新路径 ctx.beginPath(); // 位移到圆心,下面需要围绕圆心旋转 ctx.translate(105 * this.devicePixelRatio, 105 * this.devicePixelRatio); // 从(0, 0)坐标开始定义一条新的子路径 ctx.moveTo(0, 0); // 旋转弧度,需将角度转换为弧度,使用 degrees * Math.PI/180 公式进行计算。 ctx.rotate((((360 / prizeList.length) * i - rotateDeg) * Math.PI) / 180); // 绘制圆弧 ctx.arc( 0, 0, 105 * this.devicePixelRatio, 0, (2 * Math.PI) / prizeList.length, false ); // 颜色间隔 if (i % 2 == 0) { ctx.fillStyle = "#FFEAB0"; } else { ctx.fillStyle = "#ffffff"; } // 填充扇形 ctx.fill(); // 绘制边框 ctx.lineWidth = 0.5; ctx.strokeStyle = "#e4370e"; ctx.stroke(); // 恢复前一个状态 ctx.restore(); } } 复制代码
2.其次是将产品填充,做一个rotate。
_getTurnPrizeList() { const { prizeList } = this.props; const turnplateList = []; for (let i = 0; i < prizeList.length; i++) { const turnplateItem = ( <li className="turnplate-item" key={i}> <div style={{ transform: `rotate(${i / prizeList.length}turn)` }}> <div>{prizeList[i].name}</div> <img src={prizeList[i].icon} /> </div> </li> ); turnplateList.push(turnplateItem); } return <ul className="turnplate-list">{turnplateList}</ul>; } 复制代码
转盘的旋转控制
首先,能够在点击转的按钮时候做一些判断是否可以开转,使用变量canStartRotate来控制。当canStartRotate为true后,一直旋转,直到传进来的award不为空,每次transitionEnd判断award的状态,不为空就结束旋转,回调rotateFinish。
UNSAFE_componentWillReceiveProps(nextProps, nextState) { if (this.props.prizeList.length != nextProps.prizeList.length) { this.draw(); } //如果在请求,还没返回结果,就先转着 if ( !this.props.canStartRotate && nextProps.canStartRotate && !nextProps.award ) { this._initFlash(); this._outDiscFlash(); this._justRotate(); } if (!this.props.award && nextProps.award) { this.setState({ award: nextProps.award }); } } _justRotate() { const container = document.getElementById("turnplate"); const rotateDeg = 360 * 3; this.setState({ lastRotateDeg: rotateDeg + this.state.lastRotateDeg, rotating: true, justRotate: true }); container.style.transform = "rotate(" + (rotateDeg + this.state.lastRotateDeg) + "deg)"; } finishRotate() { const { rotateFinish } = this.props; const { award, justRotate } = this.state; //如果奖品来了,并且不是justRotate if (award && !justRotate) { clearTimeout(this._flashTimer); this.setState({ rotating: false }); rotateFinish(award); } //如果奖品来了,是justRotate,就开始抽 else if (award && justRotate) { this._lottery(); } else { //否则就继续等吧兄弟 this._justRotate(); } } <div className="turnplate-wrapper" id="turnplate" onTransitionEnd={this.finishRotate.bind(this)} > 复制代码
每次transition结束的时候都查看award是否已经传入,可看到finishRotate有3种情况的判断
以上所述就是小编给大家介绍的《React完美实现可配置转盘》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 微信小程序之大转盘抽奖原生开发
- 6、如何获取配置中心的配置
- React降级配置及Ant Design配置
- vscode 配置eslint 开发vue的相关配置
- git commit 规范校验配置和版本发布配置
- hadoop地址配置、内存配置、守护进程设置、环境设置
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Algorithms of the Intelligent Web
Haralambos Marmanis、Dmitry Babenko / Manning Publications / 2009-7-8 / GBP 28.99
Web 2.0 applications provide a rich user experience, but the parts you can't see are just as important-and impressive. They use powerful techniques to process information intelligently and offer featu......一起来看看 《Algorithms of the Intelligent Web》 这本书的介绍吧!