楊勝潔 鞠宏軍
摘要:《基于微信小程序的下決定轉(zhuǎn)盤(pán)》采用了微信小程序框架+微信云開(kāi)發(fā)進(jìn)行搭建,涉及JavaScript,NodeJs,Canvas等前端方面知識(shí)。開(kāi)發(fā)這款小程序的目的在于幫助更多患有選擇困難癥的人能夠快速地對(duì)一些小決定做出判斷,使用游戲的形式既能解決問(wèn)題又給生活增加了樂(lè)趣。該程序主要功能有:自定義轉(zhuǎn)盤(pán)內(nèi)容、自定義轉(zhuǎn)盤(pán)選項(xiàng)的概率、作弊模式指定轉(zhuǎn)盤(pán)的結(jié)果、按鈕觸發(fā)轉(zhuǎn)盤(pán)旋轉(zhuǎn)、手勢(shì)觸發(fā)按鈕旋轉(zhuǎn)、分享旋轉(zhuǎn)結(jié)果等。
關(guān)鍵詞:微信小程序(JavaScript);云開(kāi)發(fā)(NodeJs);選擇困難癥;轉(zhuǎn)盤(pán)(Canvas)
中圖分類(lèi)號(hào):TP311.52? ? ? 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2020)26-0004-04
Abstract:“By wheel to make decision based on WeChat small program ”uses WeChat small program framework + WeChat cloud development to build, involving JavaScript, NodeJs, Canvas and other front-end knowledge. The purpose of this small app is to help more people with choice difficulties to make quick judgments on some small decisions. Using the form of games can not only solve problems but also add fun to life. The main functions of the program are: custom rotary table content, custom rotary table option probability, cheating mode to specify the result of the rotary table, button trigger rotary table rotation, gesture trigger button rotation, share the rotary result, etc.
Key words: WeChat small program; WeChat cloud development; selective disorder; wheel
1 背景
當(dāng)前社會(huì)的發(fā)展日新月異,我們的生活也隨之發(fā)生了翻天覆地的變化。在交通工具方面,從汽車(chē)承包一切到現(xiàn)在的飛機(jī)、高鐵、滴滴打車(chē)一應(yīng)俱全;選購(gòu)商品方面,從淘寶獨(dú)掌大權(quán)到現(xiàn)在的京東、拼多多、蘇寧等電商平臺(tái)百花齊放;美食方面就更加豐富了,就連日常的生活用品都有各種各樣的品牌??萍嫉陌l(fā)展推動(dòng)了人們生活水平的提高,也催生了很多企業(yè)的發(fā)展,然后當(dāng)面對(duì)琳瑯滿(mǎn)目的商品時(shí),很多人都會(huì)陷入選擇的困境。同樣的功能,不同的款式,差不多的性?xún)r(jià)比,這些因素都導(dǎo)致了患有嚴(yán)重選擇困難癥的人群越來(lái)越多。人們往往會(huì)糾結(jié)于一些結(jié)果與產(chǎn)生的影響無(wú)關(guān)緊要的事物,比如“今天吃什么”“ 明天穿什么 ”等這一類(lèi)的問(wèn)題,然而當(dāng)我們陷入糾結(jié)的時(shí)候,無(wú)形中浪費(fèi)了很多寶貴的時(shí)間,甚至可能會(huì)錯(cuò)過(guò)某些東西,比如雙11購(gòu)物,當(dāng)你還在糾結(jié)買(mǎi)哪一款的時(shí)候優(yōu)惠已經(jīng)停止。所以,針對(duì)這樣的人群,我們需要一個(gè)能夠幫助他們做一些小決定的應(yīng)用程序,讓他們能夠?qū)ι钪械默嵤卵杆俚刈龀鲞x擇,提高生活質(zhì)量,采用轉(zhuǎn)盤(pán)的游戲形式增加生活的樂(lè)趣,減少選擇的痛苦。
2 系統(tǒng)需求分析
2.1 自定義轉(zhuǎn)盤(pán)內(nèi)容
此功能作為程序中最基本的功能,用戶(hù)可通過(guò)自己的需要,制作出相應(yīng)的轉(zhuǎn)盤(pán),在此基礎(chǔ)上,該程序還特意新增了對(duì)轉(zhuǎn)盤(pán)中每個(gè)選項(xiàng)自定義概率的功能,即當(dāng)用戶(hù)在創(chuàng)建一個(gè)新的轉(zhuǎn)盤(pán)時(shí),他可以選擇概率均分的模式,也可以選擇自定義概率的模式。
2.2 觸發(fā)轉(zhuǎn)盤(pán)旋轉(zhuǎn)
此功能也是這個(gè)程序的核心,在市面上已經(jīng)有不少類(lèi)似的小程序了,但是他們都只能夠通過(guò)按鈕來(lái)觸發(fā)轉(zhuǎn)盤(pán)的旋轉(zhuǎn),為了能夠模擬更加真實(shí)的轉(zhuǎn)盤(pán)場(chǎng)景,該程序還特意實(shí)現(xiàn)了通過(guò)移動(dòng)轉(zhuǎn)盤(pán)內(nèi)容區(qū)實(shí)現(xiàn)轉(zhuǎn)盤(pán)旋轉(zhuǎn)。
2.3 管理轉(zhuǎn)盤(pán)
此功能也是作為該程序的基礎(chǔ)功能之一。即對(duì)用戶(hù)所創(chuàng)建決定做相應(yīng)的增刪改查的操作,程序中的決定分為用戶(hù)個(gè)人的決定和熱門(mén)決定,對(duì)于用戶(hù)個(gè)人的決定,可以放心地做所有增刪改查,但對(duì)于熱門(mén)決定用戶(hù)只能夠在熱門(mén)決定的基礎(chǔ)上修改成為自己的決定,而不能夠更改熱門(mén)決定以及刪除熱門(mén)決定。
2.4 作弊模式指定旋轉(zhuǎn)結(jié)果
此功能算是該程序最有亮點(diǎn)的功能了,是為了增加程序的趣味性特意增加的該功能??梢约僭O(shè)一個(gè)場(chǎng)景,當(dāng)吃完飯決定誰(shuí)洗碗的時(shí)候,如果這時(shí)候使用下決定的作弊模式來(lái)指定某一個(gè)人,并且不告訴他,相信這個(gè)時(shí)候這個(gè)小程序就能夠給這件枯燥乏味的事情帶來(lái)一些小樂(lè)趣了。
2.5 分享用戶(hù)的旋轉(zhuǎn)結(jié)果
用戶(hù)可以將自己的旋轉(zhuǎn)結(jié)果分享給微信好友,好友點(diǎn)擊分享卡片進(jìn)入小程序,小程序會(huì)有一個(gè)初始旋轉(zhuǎn)的效果,并且旋轉(zhuǎn)結(jié)果為用戶(hù)分享的結(jié)果,并且系統(tǒng)將提示:Ta選中了……這里需要注意的是,作弊模式將不能分享。
3 系統(tǒng)設(shè)計(jì)
3.1 功能設(shè)計(jì)
1) 實(shí)現(xiàn)根據(jù)用戶(hù)輸入的轉(zhuǎn)盤(pán)選項(xiàng)進(jìn)行轉(zhuǎn)盤(pán)的繪制。
2) 實(shí)現(xiàn)轉(zhuǎn)盤(pán)的旋轉(zhuǎn),包括按鈕觸發(fā)和手勢(shì)觸發(fā)。
3) 實(shí)現(xiàn)旋轉(zhuǎn)結(jié)果的算法設(shè)計(jì)。
4) 實(shí)現(xiàn)作弊模式。
5) 實(shí)現(xiàn)對(duì)用戶(hù)個(gè)人決定的增、刪、改、查,熱門(mén)決定的查詢(xún)。
6) 實(shí)現(xiàn)對(duì)歷史記錄的增、刪、分享、查詢(xún)。
7) 實(shí)現(xiàn)分享用戶(hù)旋轉(zhuǎn)結(jié)果。
具體功能結(jié)構(gòu)如圖1所示。
3.2 系統(tǒng)總E-R圖
4 系統(tǒng)實(shí)現(xiàn)
4.1 轉(zhuǎn)盤(pán)的繪制
轉(zhuǎn)盤(pán)的繪制采用的canvas去進(jìn)行繪制的?;镜乃悸肥沁@樣的:將轉(zhuǎn)盤(pán)上的每一個(gè)選項(xiàng)看成一個(gè)扇形塊,通過(guò)找到每一個(gè)扇形塊圓弧的起始坐標(biāo)和終點(diǎn)坐標(biāo)以及原點(diǎn)坐標(biāo),通過(guò)將這三點(diǎn)連接起來(lái),再加上起始坐標(biāo)與終點(diǎn)坐標(biāo)之間的圓弧就可以繪制出一個(gè)扇形塊了,最后將扇形塊填充上指定的顏色,最后將扇形塊通過(guò)起始點(diǎn)的坐標(biāo)連接起來(lái)即可形成轉(zhuǎn)盤(pán)的樣式。
在繪制轉(zhuǎn)盤(pán)時(shí),首先就需要計(jì)算各選項(xiàng)之間的數(shù)據(jù)。在計(jì)算這些數(shù)據(jù)之前,必須知道角度與弧度之間的轉(zhuǎn)換公式:2 * Math.PI * 弧度 = 360°,這里為了方便理解,可以把轉(zhuǎn)盤(pán)的圓弧拉直,想象成一條直線(xiàn)。在繪制轉(zhuǎn)盤(pán)時(shí),需要傳入一個(gè)數(shù)組作為繪制函數(shù)的參數(shù),數(shù)組的每一項(xiàng)也就是轉(zhuǎn)盤(pán)上的每一個(gè)扇形塊,數(shù)組中每一項(xiàng)里會(huì)有一個(gè)該項(xiàng)所占總比例的多少的具體數(shù)值,這個(gè)數(shù)值就可以看成剛才所說(shuō)的那條直線(xiàn)上的線(xiàn)段,也就是轉(zhuǎn)盤(pán)上扇形塊的圓弧。因?yàn)槭峭ㄟ^(guò)canvas去進(jìn)行繪制,canvas里有一個(gè)繪制圓弧的API,content.arc()這個(gè)方法接受六個(gè)參數(shù):圓心X坐標(biāo)、圓心Y坐標(biāo)、圓的半徑、圓弧的起始角度、圓弧的終點(diǎn)角度、是否是順時(shí)針繪制,所以需要將數(shù)組中的圓弧轉(zhuǎn)換成角度傳入這個(gè)API去進(jìn)行繪制,然后再將數(shù)組中的文字填充到對(duì)應(yīng)的扇形塊即可。最后再在圓心上繪制一個(gè)轉(zhuǎn)盤(pán)指針的底座,然后在找合適的三個(gè)點(diǎn)形成一個(gè)三角形做轉(zhuǎn)盤(pán)的指針,這樣就完成了整個(gè)轉(zhuǎn)盤(pán)的繪制。效果如圖3所示。
4.2 轉(zhuǎn)盤(pán)的旋轉(zhuǎn)
轉(zhuǎn)盤(pán)繪制完成后接著就可以將轉(zhuǎn)盤(pán)旋轉(zhuǎn)起來(lái)了。旋轉(zhuǎn)的基本思路是這樣的:上面說(shuō)到轉(zhuǎn)盤(pán)中每一個(gè)扇形塊都有一個(gè)起始角度和終止角度,那么第一塊的起始角度就可以看作是整個(gè)轉(zhuǎn)盤(pán)繪制的起始角度,當(dāng)我們按照每一個(gè)扇形塊的固定角度不停地更改每一塊的起始角度,通過(guò)連續(xù)地改變角度進(jìn)行轉(zhuǎn)盤(pán)的繪制就形成了旋轉(zhuǎn)的視覺(jué)效果,效果如圖4所示。
4.3 手動(dòng)旋轉(zhuǎn)轉(zhuǎn)盤(pán)的實(shí)現(xiàn)
當(dāng)轉(zhuǎn)盤(pán)轉(zhuǎn)動(dòng)起來(lái)之后,接下來(lái)要怎么實(shí)現(xiàn)手指在轉(zhuǎn)盤(pán)上移動(dòng),轉(zhuǎn)盤(pán)也跟著旋轉(zhuǎn)呢?具體思路是這樣的:當(dāng)手指落下時(shí)需要記住手指落下的坐標(biāo),并隨時(shí)記錄手指移動(dòng)的坐標(biāo),這兩個(gè)坐標(biāo)與原點(diǎn)就形成了一個(gè)夾角,這個(gè)夾角就是轉(zhuǎn)盤(pán)需要移動(dòng)的角度。如圖5所示。
移動(dòng)夾角的計(jì)算可以通過(guò)sin、cos函數(shù)計(jì)算每一個(gè)點(diǎn)與x正向軸之間的夾角,也可以使用JavaScript的Math.atan2()API去計(jì)算相應(yīng)的角度,Math.atan2()返回的是從原點(diǎn)(0,0)到(x,y)點(diǎn)的線(xiàn)段與x軸正方向之間的平面角度(弧度值)。當(dāng)?shù)玫较鄳?yīng)的角度之后再將這個(gè)角度轉(zhuǎn)換成弧度,這個(gè)弧度也就是上面所說(shuō)的轉(zhuǎn)盤(pán)需要移動(dòng)的距離了。當(dāng)手指在轉(zhuǎn)盤(pán)上移動(dòng)的時(shí)候,不停地計(jì)算相應(yīng)的夾角,再調(diào)用相應(yīng)的轉(zhuǎn)盤(pán)繪制函數(shù)就可以實(shí)現(xiàn)手動(dòng)旋轉(zhuǎn)轉(zhuǎn)盤(pán)了。三角函數(shù)夾角計(jì)算如圖6所示。
4.4 自定義概率方法的實(shí)現(xiàn)
旋轉(zhuǎn)轉(zhuǎn)盤(pán)每一個(gè)選項(xiàng)都可以選擇1~99之間的數(shù)值,那么當(dāng)該項(xiàng)選定自己的值之后,它所占的比例就是全部選項(xiàng)的值除以本身的值,當(dāng)這個(gè)值越大那么生成的轉(zhuǎn)盤(pán)該扇形塊的面積就越大,因?yàn)樯厦嬲f(shuō)到當(dāng)繪制轉(zhuǎn)盤(pán)時(shí),會(huì)傳入一個(gè)數(shù)組作為每個(gè)扇形塊的數(shù)值,數(shù)組中每條數(shù)據(jù)都有自己所占的比例對(duì)應(yīng)的圓的弧度值。自定義概率實(shí)現(xiàn)效果如圖7所示。
4.5 轉(zhuǎn)盤(pán)旋轉(zhuǎn)結(jié)果的算法實(shí)現(xiàn)
因?yàn)樯婕白远x概率,也就是每個(gè)選項(xiàng)的概率不一定一致,因此我們需要設(shè)計(jì)一個(gè)算法去對(duì)結(jié)果進(jìn)行計(jì)算,基本的思路是這樣的:因?yàn)檫x項(xiàng)最多支持12項(xiàng),所以我們可以把所有的決定的選項(xiàng)都看作是12項(xiàng),也就是把所有的決定轉(zhuǎn)盤(pán)都看作有12個(gè)扇形塊,每個(gè)扇形塊的面積一樣,那么概率問(wèn)題就轉(zhuǎn)換為每個(gè)選項(xiàng)占多少個(gè)扇形塊的問(wèn)題了。比如有三項(xiàng)概率均分的選項(xiàng),那么每一項(xiàng)就占四個(gè)扇形塊,用它們的索引作數(shù)組項(xiàng)的話(huà),我們就可以得到這樣一個(gè)數(shù)組:[0,0,0,0,1,1,1,1,2,2,2,2]。如果有三項(xiàng)自定義概率的選項(xiàng),它們的概率分別設(shè)置為(10,20,30),那么通過(guò)計(jì)算,它們所占的圓弧比例就分別為(1/6, 1/3, 1/2),然后通過(guò)計(jì)算就可以得到最后的概率數(shù)組是:[0,0,1,1,1,1,2,2,2,2,2,2],因?yàn)檫x中每一個(gè)扇形塊的概率是一樣的,當(dāng)對(duì)應(yīng)選項(xiàng)所占的扇形塊越多,概率也就越大。這樣就實(shí)現(xiàn)了轉(zhuǎn)盤(pán)結(jié)果的計(jì)算。
4.6 作弊模式的實(shí)現(xiàn)
隨機(jī)旋轉(zhuǎn)實(shí)現(xiàn)時(shí),可以在旋轉(zhuǎn)之前就找到對(duì)應(yīng)的結(jié)果下標(biāo),只是之前討論的都是隨機(jī)從各扇形塊之間取隨機(jī)值,當(dāng)用戶(hù)選擇使用作弊模式后,就可以跳過(guò)隨機(jī)選取扇形塊這一步,之間將用戶(hù)選取的選項(xiàng)索引傳入旋轉(zhuǎn)的函數(shù)中,然后在這個(gè)選中的扇形塊的圓弧之間隨機(jī)取一個(gè)點(diǎn),計(jì)算轉(zhuǎn)盤(pán)起始點(diǎn)與這個(gè)點(diǎn)間的弧度,也就知道轉(zhuǎn)盤(pán)需要旋轉(zhuǎn)的弧度了。這里值得一提的是,當(dāng)用戶(hù)選擇了作弊模式,那么每一次的旋轉(zhuǎn)結(jié)果都將是這個(gè)結(jié)果,除非用戶(hù)手動(dòng)取消這個(gè)結(jié)果。取消的入口也設(shè)計(jì)在打開(kāi)作弊模式的入口里,這樣保證了功能的獨(dú)立性,避免出現(xiàn)UI上的冗余。作弊模式運(yùn)行效果如圖8所示。
4.7 分享功能的實(shí)現(xiàn)
關(guān)于分享功能,在這個(gè)程序里不僅做了簡(jiǎn)單地分享,還對(duì)用戶(hù)從分享的卡片進(jìn)來(lái)的效果做了處理。就是當(dāng)用戶(hù)將自己的旋轉(zhuǎn)結(jié)果分享出去的時(shí)候,會(huì)在這個(gè)分享中帶上相應(yīng)的參數(shù),也就是用戶(hù)分享出去的決定ID和選中的索引,這樣的當(dāng)被分享的用戶(hù)從分享入口進(jìn)入小程序的時(shí)候,轉(zhuǎn)盤(pán)會(huì)直接進(jìn)行一次轉(zhuǎn)動(dòng),結(jié)果也是用戶(hù)分享出去的結(jié)果,這時(shí),提示就是:「他選中了……」,這樣也在一定程度上提升了用戶(hù)的體驗(yàn),效果圖如圖9所示。
5 結(jié)束語(yǔ)
針對(duì)一些同類(lèi)的小程序進(jìn)行使用、體驗(yàn)和分析,本小程序更全面、個(gè)性化更高、體驗(yàn)更好,在原有隨機(jī)旋轉(zhuǎn)旋轉(zhuǎn)的基礎(chǔ)上增加了個(gè)性化定制轉(zhuǎn)盤(pán)、點(diǎn)擊按鈕選擇轉(zhuǎn)盤(pán)、分享轉(zhuǎn)盤(pán)的旋轉(zhuǎn)結(jié)果、默認(rèn)提供熱門(mén)決定等功能,并且添加了作弊模式指定旋轉(zhuǎn)結(jié)果、自定義轉(zhuǎn)盤(pán)選項(xiàng)概率、根據(jù)手勢(shì)移動(dòng)轉(zhuǎn)盤(pán)等亮點(diǎn)功能,從產(chǎn)品的UI設(shè)計(jì)完整性上盡可能給用戶(hù)提供最舒適的體驗(yàn)。關(guān)于技術(shù)的選型上,在調(diào)研了各種技術(shù)棧之后選擇了微信小程序開(kāi)發(fā),在數(shù)據(jù)庫(kù)和后端的處理方面選擇了微信官方提供的云開(kāi)發(fā),云開(kāi)發(fā)提供了一定限額的云數(shù)據(jù)庫(kù)以及更方便獨(dú)立開(kāi)發(fā)者的相關(guān)功能,進(jìn)一步的減少了開(kāi)發(fā)的成本,最終得以成功上線(xiàn)并進(jìn)行運(yùn)營(yíng),上線(xiàn)小程序二維碼如下圖10所示。
參考文獻(xiàn):
[1] 張帆, 陳思含. 微信小程序開(kāi)發(fā)零基礎(chǔ)入門(mén)[M].北京:電子工業(yè)出版社,2017.
[2] 阮一峰. ES6標(biāo)準(zhǔn)入門(mén)[M].3版.北京:電子工業(yè)出版社, 2017.
[3] 王延平. 21天精通微信小程序開(kāi)發(fā)[M].北京: 電子工業(yè)出版社,2017.
[4] Nicholas C Zakas. JavaScript高級(jí)程序設(shè)計(jì)[M].曹力, 張欣, 等譯.北京:人民郵電出版社,2006.
[5] 高洪濤. 從零開(kāi)始學(xué)微信小程序開(kāi)發(fā)[M].北京:電子工業(yè)出版社,2017.
[6] 樸靈. 深入淺出Node.js[M].北京:人民郵電出版社, 2013.
[7] 斯皮勒. Node.js開(kāi)發(fā)實(shí)戰(zhàn)[M].北京:人民郵電出版社, 2009.
[8] 周俊鵬. 前端工程化:體系設(shè)計(jì)與實(shí)踐[M].北京:電子工業(yè)出版社, 2018.
[9] 夜雨. Sketch交互設(shè)計(jì)之美:從零基礎(chǔ)到完整項(xiàng)目實(shí)現(xiàn)[M].北京:北京大學(xué)出版社 2018.
[10] 騰訊微信官方.微信開(kāi)發(fā)文檔[EB/OL].[2020-02-20]. https://developers.weixin.qq.com/miniprogram/dev/framework/.
【通聯(lián)編輯:謝媛媛】