成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

OpenHarmony ArkUI+原生繪圖之幸運大轉盤

開發
實現轉盤抽獎功能,可以設定中獎概率。獎項的數量、內容可自由設定,先生成一個隨機數,根據隨機數取值大小,決定獎品內容。

[[439117]]

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

效果展示

#星光計劃2.0# OpenHarmony ArkUI+原生繪圖之幸運大轉盤-鴻蒙HarmonyOS技術社區

此外,轉盤的獎項的數量,內容都是可以變動的(菜單就是用來編輯獎項的,后續完善),如下:

#星光計劃2.0# OpenHarmony ArkUI+原生繪圖之幸運大轉盤-鴻蒙HarmonyOS技術社區

主要功能

  1. 實現轉盤抽獎功能,可以設定中獎概率。
  2. 獎項的數量、內容可自由設定。
  3. 原生html\css\js代碼,沒有使用資源文件,可復用。

設計時考慮到的問題

1.控件是使用現有圖片還是通過CSS畫出?

先是用的圖片充當控件,考慮到獎項的內容可編輯性,還是老老實實畫控件比較好。

2.每個獎項的概率如何設計?

先生成一個隨機數,根據隨機數取值大小,決定獎品內容。假設所有獎項的取值范圍坐落到0100的數軸上,并且1號獎品的取值范圍是010,2號:10~30, 3號:30~35,。。。通過設定每個獎項取值區間的大小來決定中獎的權重,這樣就能控制中獎概率了。

3.如何實現獎項可編輯?

我將所有獎項存放在一個數據數組中,先能通過遍歷數組中獎項信息,畫出轉盤,這是第一步。

之后,通過菜單功能提供一個列表控件,使其能夠對數組中的信息進行增刪改查,這是第二步。

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

具體代碼

index.hml

  1. <div class="container"
  2.     <text class="title"> 幸運大轉盤 </text> 
  3.     <div class="outer" id="outer"
  4.     <!--畫布--> 
  5.         <canvas id="canvas" class="canvas"></canvas> 
  6.     <!--內圓--> 
  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"> 抽獎 </button> 
  15.         <button class="button" type="capsule" onclick="menu"> 菜單 </button> 
  16.     </div> 
  17. </div> 

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

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中的寬、高決定了轉盤大小,代碼中將轉盤的半徑設置為畫布一半寬的長度。同時,由于箭頭是由圓、長方形、正方形平移旋轉組成,那他們的偏移量、大小也是相對.canvas的屬性取的,如果大小有變動需要調整。

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

如果將箭頭也畫在畫布上,那么我不能實現轉盤轉動,箭頭不動的動畫了,畫布是一個整體。

index.js

  1. import prompt from '@system.prompt'
  2. import router from '@system.router'
  3.  
  4. export default { 
  5.     data: { 
  6.         //1.1創建獎項信息 
  7.         infoArr: [ 
  8.             { name'1號獎品' }, 
  9.             { name'2號獎品' }, 
  10.             { name'3號獎品' }, 
  11.             { name'4號獎品' }, 
  12.             { name'5號獎品' }, 
  13.             { name'6號獎品' }, 
  14.             { name'7號獎品' }, 
  15.             { name'未中獎'  }, 
  16.         ], 
  17.         //1.2畫布大小 
  18.         circleHeight: 400, 
  19.         circleWidth: 360, 
  20.         //1.3扇區弧度 
  21.         arcAngle: 0, 
  22.         //1.4扇區角度 
  23.         jiaoDu: 0, 
  24.         //1.4動畫參數 
  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.設定參數 
  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扇區角度 
  46.         this.jiaoDu = 360 / this.infoArr.length; 
  47.         //2.5定義起始弧度,箭頭向上,初始度數需要-90deg 
  48.         var beginAngle = this.arcAngle * 0.5 - 90 * Math.PI / 180; 
  49.  
  50.         //3.遍歷,繪制扇區 
  51.         for (var i = 0; i < this.infoArr.length; i++) { 
  52.             //3.1結束弧度 
  53.             var endAngle = beginAngle + this.arcAngle; 
  54.             //3.2開啟路徑 
  55.             ctx.beginPath(); 
  56.             //3.3起點 
  57.             ctx.moveTo(x0, y0); 
  58.             //3.4繪制扇區 
  59.             ctx.arc(x0, y0, radius, beginAngle, endAngle); 
  60.             //3.5設置顏色 
  61.             if (i == this.infoArr.length - 1) { 
  62.                 ctx.fillStyle = '#2f4f4f'; //未中獎灰色 
  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文字坐標 
  76.             var textX = x0 + (radius * 2 / 3) * Math.cos(textAngle); 
  77.             var textY = y0 + (radius * 2 / 3) * Math.sin(textAngle); 
  78.             //4.3平移畫布起點到文字位置 
  79.             ctx.translate(textX, textY); 
  80.             //4.4旋轉畫布 
  81.             ctx.rotate((this.jiaoDu * (i + 1) - 90) * Math.PI / 180); 
  82.             //4.5設置文字字號和字體 
  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還原旋轉、平移,方便下次旋轉 
  90.             ctx.rotate(-(this.jiaoDu * (i + 1) - 90) * Math.PI / 180); 
  91.             ctx.translate(-textX, -textY); 
  92.  
  93.             //5.更新起始弧度, 將當前扇形的結束弧度作為下一個扇形的起始弧度 
  94.             beginAngle = endAngle; 
  95.         } 
  96.     }, 
  97.  
  98.     start: function () { 
  99.         //6.旋轉事件 
  100.         //6.1獎品總數 
  101.         let count = this.infoArr.length; 
  102.         //6.2生成隨機數 
  103.         let randomNum = Math.floor(Math.random() * count); 
  104.         //6.3轉動角度(+ 360*3) 
  105.         let deg = randomNum * this.jiaoDu + 360 * 3 + "deg"
  106.         //6.4獎品名 
  107.         let index = count - randomNum - 1; 
  108.         let name = this.infoArr[index].name
  109.         console.log("name == " + name); 
  110.         //6.5動畫幀 
  111.         var frames = [ 
  112.             { 
  113.                 transform: { 
  114.                     rotate: '0deg' 
  115.                 }, 
  116.             }, 
  117.             { 
  118.                 transform: { 
  119.                     rotate: deg 
  120.                 }, 
  121.             } 
  122.         ]; 
  123.         //6.5動畫綁定 
  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調用播放開始的方法 
  138.         this.animation.play(); 
  139.     }, 
  140.  
  141.     menu: function () { 
  142.         router.push ({ 
  143.             uri: 'pages/menuPage/menuPage'
  144.         }); 
  145.     }, 

js中存放主要邏輯,所以對注釋也比較詳細。下面是個人踩坑中學習的點:

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

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2015-03-03 16:06:32

軟件圈

2018-11-13 17:12:53

戴爾

2022-08-23 16:07:02

ArkUI鴻蒙

2022-08-08 19:46:26

ArkUI鴻蒙

2022-08-12 19:13:07

etswifi連接操作

2023-08-17 15:04:22

2023-05-31 10:08:51

2022-07-26 14:40:42

ArkUIJS

2023-08-17 15:01:08

ArkUI布局渲染

2022-07-20 15:32:25

時鐘翻頁Text組件

2022-05-27 14:55:34

canvas畫布鴻蒙

2022-05-26 14:50:15

ArkUITS擴展

2022-08-24 16:08:22

ETS鴻蒙

2022-08-04 13:55:08

拼數字小游戲鴻蒙

2024-01-11 15:54:55

eTS語言TypeScript應用開發

2022-09-16 15:34:32

CanvasArkUI

2022-07-28 14:26:11

AI作詩應用開發

2022-09-15 15:04:16

ArkUI鴻蒙

2022-09-02 15:17:04

ArkUI鴻蒙

2022-09-20 14:35:59

ArkUI鴻蒙JS
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 性色av香蕉一区二区 | 一区二区三区高清在线观看 | 欧美福利在线 | 欧美精品成人影院 | 在线看免费的a | 综合精品在线 | 久久久久久成人 | 国产精品久久久久久久久久免费看 | 中文字幕av在线播放 | 亚洲国产欧美在线人成 | 五月综合久久 | 一级特黄网站 | 亚洲国产精品一区二区久久 | 日韩综合网 | 国产在线视频在线观看 | 国产资源一区二区三区 | 国产a爽一区二区久久久 | 日韩在线不卡 | 亚洲成人免费视频在线 | 亚洲视频中文字幕 | 国产精品久久国产精品 | a天堂在线 | 视频一区在线观看 | 日韩成人免费视频 | 欧美国产激情 | 亚洲一区二区三区国产 | 一区二区手机在线 | 欧美高清免费 | 国产一区二区三区视频在线观看 | 日韩在线视频精品 | 欧美日韩成人在线 | 91日日| 三级视频在线观看 | aa级毛片毛片免费观看久 | 国产中文 | 欧美日韩网站 | 户外露出一区二区三区 | 久久新 | 日韩精品在线播放 | 在线免费观看黄色 | 日韩视频二区 |