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