摘要:最近在做一些活動的需求,發(fā)現(xiàn)用到轉(zhuǎn)盤的機(jī)會很大。轉(zhuǎn)盤的旋轉(zhuǎn)控制首先,能夠在點(diǎn)擊轉(zhuǎn)的按鈕時(shí)候做一些判斷是否可以開轉(zhuǎn),使用變量來控制。
最近在做一些h5活動的需求,發(fā)現(xiàn)用到轉(zhuǎn)盤的機(jī)會很大。
代碼已經(jīng)開源,感興趣的同學(xué)可查看react-turnplate
先上效果額,因?yàn)間if壓縮了,所以畫質(zhì)有點(diǎn)。。。呵呵,沒關(guān)系的
需求
于是將轉(zhuǎn)盤組件化,具體的需求是:
傳入一個(gè)獎品數(shù)組.
能夠在點(diǎn)擊轉(zhuǎn)的按鈕時(shí)候做一些判斷是否可以開轉(zhuǎn).
開轉(zhuǎn)后有一個(gè)回調(diào),用于請求獎品返回.
轉(zhuǎn)動結(jié)束/中獎回調(diào).
轉(zhuǎn)動按鈕,背景圖可配置. 具體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 |
這里主要是兩張背景圖不斷替換,通過定時(shí)器,不斷替換background形成閃爍的效果.
//外面閃閃發(fā)光的東東 _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.首先是根據(jù)傳進(jìn)來的獎品數(shù)組個(gè)數(shù),用canvas來畫扇形填充。用devicePixelRatio是為了適配手機(jī)。
draw() { const { prizeList } = this.props; let rotateDeg = 360 / prizeList.length / 2 + 90, // 扇形回轉(zhuǎn)角度 ctx; const canvas = document.getElementById("canvas"); if (!canvas.getContext) { return; } // 獲取繪圖上下文 ctx = canvas.getContext("2d"); for (let i = 0; i < prizeList.length; i++) { // 保存當(dāng)前狀態(tài) ctx.save(); // 開始一條新路徑 ctx.beginPath(); // 位移到圓心,下面需要圍繞圓心旋轉(zhuǎn) ctx.translate(105 * this.devicePixelRatio, 105 * this.devicePixelRatio); // 從(0, 0)坐標(biāo)開始定義一條新的子路徑 ctx.moveTo(0, 0); // 旋轉(zhuǎn)弧度,需將角度轉(zhuǎn)換為弧度,使用 degrees * Math.PI/180 公式進(jìn)行計(jì)算。 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(); // 恢復(fù)前一個(gè)狀態(tài) ctx.restore(); } }2.其次是將產(chǎn)品填充,做一個(gè)rotate。
_getTurnPrizeList() { const { prizeList } = this.props; const turnplateList = []; for (let i = 0; i < prizeList.length; i++) { const turnplateItem = (首先,能夠在點(diǎn)擊轉(zhuǎn)的按鈕時(shí)候做一些判斷是否可以開轉(zhuǎn),使用變量canStartRotate來控制。當(dāng)canStartRotate為true后,一直旋轉(zhuǎn),直到傳進(jìn)來的award不為空,每次transitionEnd判斷award的狀態(tài),不為空就結(jié)束旋轉(zhuǎn),回調(diào)rotateFinish。
UNSAFE_componentWillReceiveProps(nextProps, nextState) { if (this.props.prizeList.length != nextProps.prizeList.length) { this.draw(); } //如果在請求,還沒返回結(jié)果,就先轉(zhuǎn)著 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 { //否則就繼續(xù)等吧兄弟 this._justRotate(); } }每次transition結(jié)束的時(shí)候都查看award是否已經(jīng)傳入,可看到finishRotate有3種情況的判斷
待實(shí)現(xiàn)的功能轉(zhuǎn)盤大小可配置
轉(zhuǎn)盤每個(gè)扇形顏色可配置 ....
這些之后都會在react-turnplate完善。
此處只是提供了一種思路,拋磚引玉。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/6744.html
摘要:效果需求很多場景都需要做各種活動,抽獎最是司空見慣了,跑馬燈的,轉(zhuǎn)盤的,下面先花幾分鐘擼出一個(gè)轉(zhuǎn)盤的吧,當(dāng)然網(wǎng)上至少有一打的可供參考。但是我們只差一個(gè)定時(shí)器循環(huán)了接下里實(shí)現(xiàn)這個(gè)主循環(huán),不斷更新值就可以了。 demo 效果 需求 很多場景都需要做各種活動,抽獎最是司空見慣了,跑馬燈的,轉(zhuǎn)盤的,下面先花幾分鐘擼出一個(gè)轉(zhuǎn)盤的吧,當(dāng)然網(wǎng)上至少有一打的 demo 可供參考。真的只需要一點(diǎn)點(diǎn)時(shí)間而...
摘要:快速開始下載碼云高速下載安裝執(zhí)行包安裝,如無,請先執(zhí)行自動創(chuàng)建數(shù)據(jù)庫配置必須使用必須使用必須使用運(yùn)行更新月報(bào)年月年月年月年月年月年月年月年月年月下載地址碼云一點(diǎn)說明月將發(fā)布用戶中心模塊和模塊,月月后續(xù)還會有商城模塊微信模塊 前言 大多數(shù) node.js 框架都沒解決架構(gòu)問題,使得 node.js 沒能像 spring 一樣的適合大型項(xiàng)目開發(fā)和維護(hù)的框架。 nest.js 出現(xiàn)改變了這種...
摘要:最近工作中重構(gòu)了抽獎轉(zhuǎn)盤,給大家提供一個(gè)開發(fā)轉(zhuǎn)盤抽獎的思路需求轉(zhuǎn)盤根據(jù)獎品數(shù)量不同而有變化目錄結(jié)構(gòu)由于業(yè)務(wù)需要所以開發(fā)了兩個(gè)版本抽獎,和,不過部分只能替換圖片,沒有功能邏輯。 最近工作中重構(gòu)了抽獎轉(zhuǎn)盤,給大家提供一個(gè)開發(fā)轉(zhuǎn)盤抽獎的思路 需求 1、轉(zhuǎn)盤根據(jù)獎品數(shù)量不同而有變化 2、canvas 目錄結(jié)構(gòu) showImg(https://segmentfault.com/img/bVbwL...
摘要:項(xiàng)目主要是微信小程序也用到了等。前端部分主要是歌曲播放控制和交互部分的代碼,更多關(guān)于小程序的內(nèi)容可見微信小程序開發(fā)文檔小程序框架結(jié)構(gòu)微信小程序的入口是根目錄下的它們分別描述的小程序的主題邏輯和公共配置部分。 剛進(jìn)公司不久,因?yàn)楣静块T年后業(yè)務(wù)拓展的關(guān)系,可能在年后會被分配到公司的微信公眾號組做小程序相關(guān)的開發(fā)工作,因此寫了個(gè)微信小程序wx-audio踩坑。目前還有一些功能沒有寫完:如返...
閱讀 1173·2021-11-22 15:22
閱讀 3847·2021-10-19 13:13
閱讀 3596·2021-10-08 10:05
閱讀 3305·2021-09-26 10:20
閱讀 2993·2019-08-29 14:21
閱讀 2203·2019-08-27 10:55
閱讀 1879·2019-08-26 10:31
閱讀 2588·2019-08-23 16:47