自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

OpenHarmony ArkUI+原生繪圖之幸運(yùn)大轉(zhuǎn)盤

開發(fā)
實(shí)現(xiàn)轉(zhuǎn)盤抽獎(jiǎng)功能,可以設(shè)定中獎(jiǎng)概率。獎(jiǎng)項(xiàng)的數(shù)量、內(nèi)容可自由設(shè)定,先生成一個(gè)隨機(jī)數(shù),根據(jù)隨機(jī)數(shù)取值大小,決定獎(jiǎng)品內(nèi)容。

[[439117]]

想了解更多內(nèi)容,請?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

效果展示

#星光計(jì)劃2.0# OpenHarmony ArkUI+原生繪圖之幸運(yùn)大轉(zhuǎn)盤-鴻蒙HarmonyOS技術(shù)社區(qū)

此外,轉(zhuǎn)盤的獎(jiǎng)項(xiàng)的數(shù)量,內(nèi)容都是可以變動(dòng)的(菜單就是用來編輯獎(jiǎng)項(xiàng)的,后續(xù)完善),如下:

#星光計(jì)劃2.0# OpenHarmony ArkUI+原生繪圖之幸運(yùn)大轉(zhuǎn)盤-鴻蒙HarmonyOS技術(shù)社區(qū)

主要功能

  1. 實(shí)現(xiàn)轉(zhuǎn)盤抽獎(jiǎng)功能,可以設(shè)定中獎(jiǎng)概率。
  2. 獎(jiǎng)項(xiàng)的數(shù)量、內(nèi)容可自由設(shè)定。
  3. 原生html\css\js代碼,沒有使用資源文件,可復(fù)用。

設(shè)計(jì)時(shí)考慮到的問題

1.控件是使用現(xiàn)有圖片還是通過CSS畫出?

先是用的圖片充當(dāng)控件,考慮到獎(jiǎng)項(xiàng)的內(nèi)容可編輯性,還是老老實(shí)實(shí)畫控件比較好。

2.每個(gè)獎(jiǎng)項(xiàng)的概率如何設(shè)計(jì)?

先生成一個(gè)隨機(jī)數(shù),根據(jù)隨機(jī)數(shù)取值大小,決定獎(jiǎng)品內(nèi)容。假設(shè)所有獎(jiǎng)項(xiàng)的取值范圍坐落到0100的數(shù)軸上,并且1號(hào)獎(jiǎng)品的取值范圍是010,2號(hào):10~30, 3號(hào):30~35,。。。通過設(shè)定每個(gè)獎(jiǎng)項(xiàng)取值區(qū)間的大小來決定中獎(jiǎng)的權(quán)重,這樣就能控制中獎(jiǎng)概率了。

3.如何實(shí)現(xiàn)獎(jiǎng)項(xiàng)可編輯?

我將所有獎(jiǎng)項(xiàng)存放在一個(gè)數(shù)據(jù)數(shù)組中,先能通過遍歷數(shù)組中獎(jiǎng)項(xiàng)信息,畫出轉(zhuǎn)盤,這是第一步。

之后,通過菜單功能提供一個(gè)列表控件,使其能夠?qū)?shù)組中的信息進(jìn)行增刪改查,這是第二步。

在界面加載的onShow()函數(shù)中進(jìn)行初始化,這樣每次界面顯示的時(shí)候就能更新轉(zhuǎn)盤了。

具體代碼

index.hml

  1. <div class="container"
  2.     <text class="title"> 幸運(yùn)大轉(zhuǎn)盤 </text> 
  3.     <div class="outer" id="outer"
  4.     <!--畫布--> 
  5.         <canvas id="canvas" class="canvas"></canvas> 
  6.     <!--內(nèi)圓--> 
  7.         <div class="circle"></div> 
  8.     <!--長方形--> 
  9.         <div class="rectangle"></div> 
  10.     <!--正方形箭頭--> 
  11.         <div class="square"></div> 
  12.     </div> 
  13.     <div class="btns"
  14.         <button class="button" type="capsule" onclick="start"> 抽獎(jiǎng) </button> 
  15.         <button class="button" type="capsule" onclick="menu"> 菜單 </button> 
  16.     </div> 
  17. </div> 

outer就是轉(zhuǎn)盤整體,包含轉(zhuǎn)盤和箭頭。我箭頭是通過將圓+長方形+正方形平移、旋轉(zhuǎn)組合而成的(雖然有點(diǎn)笨,沒有想到其它辦法)。轉(zhuǎn)盤是一個(gè)畫布canvas,通過移動(dòng)畫筆起點(diǎn),旋轉(zhuǎn),一個(gè)扇區(qū)接一個(gè)扇區(qū)畫出的。按鍵有兩個(gè),抽獎(jiǎng)就是轉(zhuǎn)動(dòng)轉(zhuǎn)盤,實(shí)現(xiàn)抽獎(jiǎng)邏輯。菜單按鍵跳轉(zhuǎn)到新的界面,實(shí)現(xiàn)獎(jiǎng)項(xiàng)內(nèi)容的編輯,當(dāng)然還沒寫完。。。 

index.css

  1. .container { 
  2.     flex-direction: column
  3.     align-items: center; 
  4.     justify-content: space-between
  5.  
  6. .title { 
  7.     font-size: 38px; 
  8.     font-weight: 600; 
  9.     height: 20%; 
  10.  
  11. .outer { 
  12.     position: relative
  13.  
  14. .canvas { 
  15.     width: 360px; 
  16.     height: 400px; 
  17.  
  18. .circle { 
  19.     position: absolute
  20.     width: 40px; 
  21.     height: 40px; 
  22.     background-color: darkred; 
  23.     border-radius: 20px; 
  24.     transform: translate(160px,180px); 
  25.  
  26. .rectangle { 
  27.     position: absolute
  28.     width: 20px; 
  29.     height: 40px; 
  30.     background-color: darkred; 
  31.     transform: translate(170px,150px); 
  32.  
  33. .square { 
  34.     position:absolute
  35.     width: 20px; 
  36.     height: 20px; 
  37.     background-color: darkred; 
  38.     top: 140px; 
  39.     left: 170px; 
  40.     transform: rotate(45deg); 
  41.  
  42. .btns { 
  43.     justify-content:space-around; 
  44.  
  45. .button{ 
  46.     margin-top: 10%; 
  47.     height: 10%; 
  48.     font-size: 30px; 
  49.     font-weight: 600; 

canvas中的寬、高決定了轉(zhuǎn)盤大小,代碼中將轉(zhuǎn)盤的半徑設(shè)置為畫布一半寬的長度。同時(shí),由于箭頭是由圓、長方形、正方形平移旋轉(zhuǎn)組成,那他們的偏移量、大小也是相對.canvas的屬性取的,如果大小有變動(dòng)需要調(diào)整。

為什么不將箭頭也畫出來?

如果將箭頭也畫在畫布上,那么我不能實(shí)現(xiàn)轉(zhuǎn)盤轉(zhuǎn)動(dòng),箭頭不動(dòng)的動(dòng)畫了,畫布是一個(gè)整體。

index.js

  1. import prompt from '@system.prompt'
  2. import router from '@system.router'
  3.  
  4. export default { 
  5.     data: { 
  6.         //1.1創(chuàng)建獎(jiǎng)項(xiàng)信息 
  7.         infoArr: [ 
  8.             { name'1號(hào)獎(jiǎng)品' }, 
  9.             { name'2號(hào)獎(jiǎng)品' }, 
  10.             { name'3號(hào)獎(jiǎng)品' }, 
  11.             { name'4號(hào)獎(jiǎng)品' }, 
  12.             { name'5號(hào)獎(jiǎng)品' }, 
  13.             { name'6號(hào)獎(jiǎng)品' }, 
  14.             { name'7號(hào)獎(jiǎng)品' }, 
  15.             { name'未中獎(jiǎng)'  }, 
  16.         ], 
  17.         //1.2畫布大小 
  18.         circleHeight: 400, 
  19.         circleWidth: 360, 
  20.         //1.3扇區(qū)弧度 
  21.         arcAngle: 0, 
  22.         //1.4扇區(qū)角度 
  23.         jiaoDu: 0, 
  24.         //1.4動(dòng)畫參數(shù) 
  25.         animation: ''
  26.         options: { 
  27.             duration: 5000, 
  28.             fill: 'forwards'
  29.             easing: 'cubic-bezier(.2,.93,.43,1);'
  30.         }, 
  31.     }, 
  32.  
  33.     onShow() { 
  34.         const ca = this.$element('canvas'); 
  35.         const ctx = ca.getContext('2d'); 
  36.  
  37.         //2.設(shè)定參數(shù) 
  38.         //2.1定義圓心,顯示在畫布中間 
  39.         var x0 = this.circleWidth * 0.5; 
  40.         var y0 = this.circleHeight * 0.5; 
  41.         //2.2定義半徑 
  42.         var radius = this.circleWidth * 0.5; 
  43.         //2.3扇形弧度 
  44.         this.arcAngle = 360 / this.infoArr.length * Math.PI / 180; 
  45.         //2.4扇區(qū)角度 
  46.         this.jiaoDu = 360 / this.infoArr.length; 
  47.         //2.5定義起始弧度,箭頭向上,初始度數(shù)需要-90deg 
  48.         var beginAngle = this.arcAngle * 0.5 - 90 * Math.PI / 180; 
  49.  
  50.         //3.遍歷,繪制扇區(qū) 
  51.         for (var i = 0; i < this.infoArr.length; i++) { 
  52.             //3.1結(jié)束弧度 
  53.             var endAngle = beginAngle + this.arcAngle; 
  54.             //3.2開啟路徑 
  55.             ctx.beginPath(); 
  56.             //3.3起點(diǎn) 
  57.             ctx.moveTo(x0, y0); 
  58.             //3.4繪制扇區(qū) 
  59.             ctx.arc(x0, y0, radius, beginAngle, endAngle); 
  60.             //3.5設(shè)置顏色 
  61.             if (i == this.infoArr.length - 1) { 
  62.                 ctx.fillStyle = '#2f4f4f'; //未中獎(jiǎng)灰色 
  63.             } else if (i % 2) { 
  64.                 ctx.fillStyle = '#ffa500'
  65.             } else { 
  66.                 ctx.fillStyle = '#ff4500'
  67.             } 
  68.             //3.6填充顏色 
  69.             ctx.fill(); 
  70.  
  71.             //4.繪制文字 
  72.             //4.1文字弧度 
  73.             var textAngle = beginAngle + this.arcAngle * 0.5; 
  74.             var text = this.infoArr[i].name
  75.             //4.2文字坐標(biāo) 
  76.             var textX = x0 + (radius * 2 / 3) * Math.cos(textAngle); 
  77.             var textY = y0 + (radius * 2 / 3) * Math.sin(textAngle); 
  78.             //4.3平移畫布起點(diǎn)到文字位置 
  79.             ctx.translate(textX, textY); 
  80.             //4.4旋轉(zhuǎn)畫布 
  81.             ctx.rotate((this.jiaoDu * (i + 1) - 90) * Math.PI / 180); 
  82.             //4.5設(shè)置文字字號(hào)和字體 
  83.             ctx.font = "25px '微軟雅黑'"
  84.             //4.6文字居中對齊 
  85.             ctx.textAlign = 'center'
  86.             ctx.textBaseline = 'middle'
  87.             //4.7繪制文字 
  88.             ctx.strokeText(text, 0, 0); 
  89.             //4.8還原旋轉(zhuǎn)、平移,方便下次旋轉(zhuǎn) 
  90.             ctx.rotate(-(this.jiaoDu * (i + 1) - 90) * Math.PI / 180); 
  91.             ctx.translate(-textX, -textY); 
  92.  
  93.             //5.更新起始弧度, 將當(dāng)前扇形的結(jié)束弧度作為下一個(gè)扇形的起始弧度 
  94.             beginAngle = endAngle; 
  95.         } 
  96.     }, 
  97.  
  98.     start: function () { 
  99.         //6.旋轉(zhuǎn)事件 
  100.         //6.1獎(jiǎng)品總數(shù) 
  101.         let count = this.infoArr.length; 
  102.         //6.2生成隨機(jī)數(shù) 
  103.         let randomNum = Math.floor(Math.random() * count); 
  104.         //6.3轉(zhuǎn)動(dòng)角度(+ 360*3) 
  105.         let deg = randomNum * this.jiaoDu + 360 * 3 + "deg"
  106.         //6.4獎(jiǎng)品名 
  107.         let index = count - randomNum - 1; 
  108.         let name = this.infoArr[index].name
  109.         console.log("name == " + name); 
  110.         //6.5動(dòng)畫幀 
  111.         var frames = [ 
  112.             { 
  113.                 transform: { 
  114.                     rotate: '0deg' 
  115.                 }, 
  116.             }, 
  117.             { 
  118.                 transform: { 
  119.                     rotate: deg 
  120.                 }, 
  121.             } 
  122.         ]; 
  123.         //6.5動(dòng)畫綁定 
  124.         this.animation = this.$element('canvas').animate(frames, this.options); 
  125.         //6.6添加完成事件 
  126.         this.animation.onfinish = function () { 
  127.             if (randomNum % count) { 
  128.                 prompt.showDialog({ 
  129.                     message: "恭喜抽中" + name + "!" 
  130.                 }); 
  131.             } else { 
  132.                 prompt.showDialog({ 
  133.                     message: "下次再來!" 
  134.                 }); 
  135.             } 
  136.         }; 
  137.         //6.7調(diào)用播放開始的方法 
  138.         this.animation.play(); 
  139.     }, 
  140.  
  141.     menu: function () { 
  142.         router.push ({ 
  143.             uri: 'pages/menuPage/menuPage'
  144.         }); 
  145.     }, 

js中存放主要邏輯,所以對注釋也比較詳細(xì)。下面是個(gè)人踩坑中學(xué)習(xí)的點(diǎn):

  1. //1.1創(chuàng)建獎(jiǎng)項(xiàng)信息 
  2. 可以增加減少獎(jiǎng)項(xiàng)來預(yù)覽將要實(shí)現(xiàn)的菜單功能,不要搞事情哈,獎(jiǎng)項(xiàng)至少為1,代碼中沒有除0保護(hù)。 
  3. //1.4動(dòng)畫參數(shù) 
  4. duration是時(shí)長。easing,是描述動(dòng)畫的時(shí)間曲線,實(shí)現(xiàn)動(dòng)畫由快變慢。fill:forwards在動(dòng)畫結(jié)束后,目標(biāo)將保留動(dòng)畫結(jié)束時(shí)的狀態(tài)。 
  5. //3.4繪制扇區(qū) 
  6. x0, y0,扇區(qū)的起點(diǎn)坐標(biāo)。radius,扇區(qū)半徑。beginAngle,扇區(qū)起始的弧度,endAngle,扇區(qū)結(jié)束的弧度。 
  7. //3.5設(shè)置顏色 
  8. 每個(gè)扇區(qū)設(shè)置兩個(gè)相間的顏色,未中獎(jiǎng)特殊扇區(qū)用灰色調(diào)標(biāo)識(shí)。 
  9. //4.2文字坐標(biāo) 
  10. 由于文字在扇區(qū)中間,所以需要利用正弦余弦計(jì)算坐標(biāo),再進(jìn)行畫面旋轉(zhuǎn),才能調(diào)整正確的文字方向。 
  11. //4.8還原旋轉(zhuǎn)、平移,方便下次旋轉(zhuǎn) 
  12. translate函數(shù)是基于當(dāng)前坐標(biāo)進(jìn)行偏移,旋轉(zhuǎn)也是基于當(dāng)前坐標(biāo)進(jìn)行旋轉(zhuǎn)。所以當(dāng)一個(gè)扇區(qū)的文字填寫結(jié)束后,需要將坐標(biāo)還原,這樣才方便定位到一下處扇區(qū)位置。 

想了解更多內(nèi)容,請?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2015-03-03 16:06:32

軟件圈

2018-11-13 17:12:53

戴爾

2022-08-23 16:07:02

ArkUI鴻蒙

2022-08-12 19:13:07

etswifi連接操作

2022-08-08 19:46:26

ArkUI鴻蒙

2023-08-17 15:01:08

ArkUI布局渲染

2022-07-20 15:32:25

時(shí)鐘翻頁Text組件

2023-05-31 10:08:51

2023-08-17 15:04:22

2024-01-11 15:54:55

eTS語言TypeScript應(yīng)用開發(fā)

2022-07-26 14:40:42

ArkUIJS

2022-05-26 14:50:15

ArkUITS擴(kuò)展

2022-05-27 14:55:34

canvas畫布鴻蒙

2022-08-24 16:08:22

ETS鴻蒙

2023-03-13 15:03:05

鴻蒙ArkUI

2022-09-02 15:17:04

ArkUI鴻蒙

2022-09-20 14:35:59

ArkUI鴻蒙JS

2022-09-15 15:04:16

ArkUI鴻蒙

2022-08-04 13:55:08

拼數(shù)字小游戲鴻蒙

2022-03-03 18:39:01

Harmonyioremap鴻蒙
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)