主頁 > 移動端開發 > uni-app初探之幸運輪盤

uni-app初探之幸運輪盤

2020-11-22 00:39:36 移動端開發

uni-app以其“一次開發,多端覆寫”的理念深得大家青睞,并且生態環境豐富,本文以一個幸運輪盤小例子,簡述canvas的相關操作,僅供學習分享使用,如有不足之處,還請指正,

什么是canvas?

canvas又稱畫布,為uni-app提供自定義繪制的區域,通常用于圖表或者圖片的處理,在uni-app開發中,如果要在canvas中進行繪制,需要通過CanvasContext完成,

canvas相關知識點

canvas屬性說明【canvas-id 在同一頁面中不可重復】

CanvasContext的定義通過uni-app提供的API【uni.createCanvasContext(canvasId, this)】完成,如下所示:

 在canvas上進行繪制,主要通過CanvasContex物件進行,關于CanvasContext的使用方法,可參考官方檔案,

示例效果圖

在Chrome瀏覽器上,如下所示:

在Android手機上,如下圖所示:

核心源代碼

在uni-app開發中,一個功能可以封裝成一個控制元件,便于維護和呼叫,

本例Lottery控制元件的template原始碼如下:

 1 <template>
 2     <view class="content1">
 3         <canvas type="2D" canvas-id="canvas" id="canvas" :style="canvasStyle">
 4 
 5         </canvas>
 6         <image :src="inLottery?'../../static/img/start_disabled.png':'../../static/img/start.png'" id="start" @tap="playReward"></image>
 7         <view class="bottom1">
 8             <image src="../../static/img/xiaolian.png" class="smile"></image>
 9             <view class="winner">{{winner}}</view>
10         </view>
11         
12     </view>
13 </template>
View Code

本例Lottery控制元件的JavaScript原始碼如下:

  1 <script>
  2     var ctx = null;
  3     export default {
  4         props: {
  5             lwidth: {
  6                 type: Number,
  7                 default: 100,
  8 
  9             },
 10             lheight: {
 11                 type: Number,
 12                 default: 100
 13             },
 14             inLottery: {
 15                 type: Boolean,
 16                 default: false
 17             },
 18             
 19             parts: {
 20                 type: Array,
 21                 default: function() {
 22                     return [{
 23                             id: 1,
 24                             name: '香蕉',
 25                             img: '',
 26                             color: "#AABBCC"
 27                         },
 28                         {
 29                             id: 2,
 30                             name: '蘋果',
 31                             img: '',
 32                             color: "#FFCCFF"
 33                         },
 34                         {
 35                             id: 3,
 36                             name: '梨子',
 37                             img: '',
 38                             color: "#FFFFFF"
 39                         },
 40                         {
 41                             id: 4,
 42                             name: '青瓜',
 43                             img: '',
 44                             color: "#FFCCFF"
 45                         },
 46                         {
 47                             id: 5,
 48                             name: '番茄',
 49                             img: '',
 50                             color: "#FFFFFF"
 51                         }
 52                     ]
 53                 }
 54             }
 55         },
 56         data() {
 57             return {
 58                 winner:"請抽獎"
 59             };
 60         },
 61         computed: {
 62             canvasStyle() {
 63                 return {
 64                     width: (this.lwidth) + "px",
 65                     height: (this.lheight) + "px"
 66                 };
 67             },
 68             
 69         },
 70         methods: {
 71             initLottery:function(ctx,angleTo){
 72                 
 73                 const len = this.parts.length; //陣列長度
 74                 if (len == 0) {
 75                     return;
 76                 }
 77                 var center_x = this.lwidth / 2;
 78                 var center_y = this.lheight / 2;
 79                 var total = 2 * Math.PI; //總度數為2π
 80                 var Angle = total / len; //平均值
 81                 var radius = center_x - 14;
 82                 center_x = center_x;
 83                 center_y = center_y;
 84                 angleTo = angleTo || 0;
 85                 ctx.clearRect(0,0, this.lwidth, this.lheight);
 86                 ctx.translate(center_x, center_y);
 87                 ctx.setFontSize(14);
 88                 ctx.setLineWidth(14);
 89                 ctx.save();
 90                 //旋轉畫布
 91                 ctx.rotate(angleTo * Math.PI / 180);
 92                 //
 93                 var beginAngle = 2 * Math.PI / 360 * (-90);
 94                 //先畫外圓
 95                 ctx.setStrokeStyle("#ffaa00");
 96                 ctx.arc(0, 0, radius + 3, 0, Math.PI * 2);
 97                 ctx.stroke();
 98                 //畫裝飾點
 99                 for (var i = 0; i < 24; i++) {
100                     // 裝飾點 圓心 坐標計算
101                     ctx.beginPath();
102                     var r = radius + 6;
103                     var xr = r * Math.cos(beginAngle);
104                     var yr = r * Math.sin(beginAngle);
105                 
106                     ctx.fillStyle = "#FFFFFF";
107                     ctx.arc(xr, yr, 4, 0, 2 * Math.PI);
108                     ctx.fill();
109                 
110                     beginAngle += (2 * Math.PI / 360) * (360 / 24);
111                 
112                 }
113                 ctx.setLineWidth(0.1);
114                 beginAngle = 2 * Math.PI / 360 * (-90);
115                 //繪制填充形狀
116                 for (var i = 0; i < len; i++) {
117                     // console.log("color = "+this.parts[i].color);
118                     // console.log("beginAngle="+beginAngle);
119                     ctx.save();
120                     ctx.beginPath();
121                     ctx.moveTo(0, 0);
122                     ctx.setStrokeStyle(this.parts[i].color);
123                     ctx.setFillStyle(this.parts[i].color);
124                 
125                     ctx.arc(0, 0, radius, beginAngle, beginAngle + Angle, false);
126                     //ctx.stroke();
127                     ctx.fill();
128                     ctx.save();
129                     beginAngle = beginAngle + Angle;
130                 }
131                 beginAngle = 0; //Angle / 2;
132                 for (var i = 0; i < len; i++) {
133                     var ry = -(center_x / 2) - 25;
134                     //繪制旋轉文字
135                     ctx.rotate((beginAngle + (Angle * 0.5))); //順時針旋轉
136                     ctx.setTextAlign("center");
137                     ctx.setFillStyle("#AA00CC");
138                     ctx.fillText(this.parts[i].name, 0, ry);
139                 
140                     ctx.restore();
141                     beginAngle = beginAngle + Angle;
142                 }
143                 ctx.save();
144                 ctx.beginPath();
145                 ctx.arc(0, 0, 8, 0, Math.PI * 2);
146                 ctx.setFillStyle("#FFFFFF");
147                 ctx.fill();
148                 ctx.draw();
149             },
150             playReward:function(){
151                 var len = this.parts.length; //陣列長度
152                 if (len == 0) {
153                     return;
154                 }
155                 var angle = 360/len ; 
156                 var num =Math.floor(Math.random()*len);
157                 //num= num%len;
158                 angle = num * angle + angle / 2;
159                 angle = angle || 0;
160                 angle = 360-angle;
161                 angle += 1440;
162                 console.log("angle = "+angle +",num = "+num);
163                 var that = this;
164                 var count = 1;
165                 // 基值(減速)
166                 var baseStep = 50;
167                 // 起始滾動速度
168                 var baseSpeed =1;
169                 var timer = setInterval(function(){
170                     console.log("count = "+count);
171                     that.initLottery(that.ctx,count) ;
172                     if (count == angle) {
173                         clearInterval(timer);
174                         that.winner = "當前獎品為:"+that.parts[num].name;
175                     }
176                     count =  count + baseStep * (((angle - count) / angle) > baseSpeed ? baseSpeed : ((angle - count) / angle))+0.1;
177                     if (angle - count < 0.5) {
178                         count = angle;
179                     }
180                 },25);
181             }
182         },
183         // 組件內么有onReady和onLoad等生命周期
184         mounted: function() {
185             this.ctx = uni.createCanvasContext("canvas");
186             this.initLottery(this.ctx,0);
187         }
188     }
189 </script>
View Code

 本例Lottery控制元件的CSS原始碼如下:

 1 <style>
 2     .content1 {
 3         width: 100%;
 4         height: 100%;
 5         text-align: center;
 6         display: flex;
 7         flex-direction: column;
 8         align-items: center;
 9         position: relative;
10     }
11 
12     #canvas {
13         left: 2rpx;
14         top: 2rpx;
15     }
16 
17     #start {
18         position: absolute;
19         width: 110rpx;
20         height: 150rpx;
21         cursor: pointer;
22         top: 240rpx;
23     }
24     .bottom1{
25         display: flex;
26         flex-direction: row;
27         justify-content: center;
28         justify-content: center;
29     }
30     .winner{
31         height: 70rpx;
32         vertical-align: middle;
33         padding-top: 10rpx;
34         color: #FFFFFF;
35     }
36     .smile{
37         width: 70rpx;
38         height: 70rpx;
39     }
40 </style>
View Code

 本例index頁面呼叫組件,代碼如下:

 1 <template>
 2     <view class="content">
 3         <view class="top"></view>
 4         <lottery  class="lottery" :lwidth="lwidth" :lheight="lheight"></lottery>
 5         <view class="bottom">Provider By Alan.hsiang</view>
 6     </view>
 7 </template>
 8 
 9 <script>
10     import lottery from "@/components/Lottery/Lottery.vue"
11     export default {
12         components:{
13             lottery
14         },
15         data() {
16             return {
17                 title: 'Hello',
18                 lwidth:300,
19                 lheight:300
20             }
21         },
22         onl oad() {
23 
24         },
25         methods: {
26 
27         }
28     }
29 </script>
30 
31 <style>
32     .content {
33         display: flex;
34         flex-direction: column;
35         /* align-items: center; */
36         /* justify-content: center; */
37         background-image: url(../../static/img/bg.jpg);
38         background-position: center;
39         background-repeat: no-repeat;
40         background-size: cover;
41         height: 100%;
42         width: 100%;
43     }
44     .top{
45         height: 35%;
46         width: 100%;
47     }
48     .lottery{
49         /* position: absolute; */
50         /* top: 200rpx; */
51         /* bottom: 200rpx; */
52         margin: 2rpx;
53         width: 100%;
54         height: 700rpx;
55     }
56     .bottom{
57         position: absolute;
58         bottom: 10rpx;
59         color: #FFFFFF;
60         width: 100%;
61         text-align: center;
62     }
63 </style>
View Code

另外為了頁面顯示完整,需要在App.vue中定義頁面顯示100%,如下所示:

 1 <script>
 2     export default {
 3         onLaunch: function() {
 4             console.log('App Launch')
 5         },
 6         onShow: function() {
 7             console.log('App Show')
 8         },
 9         onHide: function() {
10             console.log('App Hide')
11         }
12     }
13 </script>
14 
15 <style>
16     /*每個頁面公共css */
17     uni-page-body,#app {width:100%;height: 100%;}
18     page{
19         width: 100%;
20         height: 100%;
21     }
22 </style>
View Code

備注

八聲甘州·對瀟瀟暮雨灑江天
【作者】柳永 【朝代】宋 對瀟瀟暮雨灑江天,一番洗清秋,
漸霜風凄緊,關河冷落,殘照當樓,
是處紅衰翠減,苒苒物華休,
惟有長江水,無語東流,   不忍登高臨遠,望故鄉渺邈,歸思難收,
嘆年來蹤跡,何事苦淹留?
想佳人、妝樓颙望,誤幾回、天際識歸舟,
爭知我,倚欄桿處,正恁凝愁,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/226078.html

標籤:其他

上一篇:1. RxSwift 創建可觀程式列

下一篇:小白 求助

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more