最近剛好接手支持了每日出擊運簽的小程序,在小程序完成以后,整理了一下初次接手小程序的一些體驗,所以有了現在這篇小總結。在小程序需求的進行期間,十分感謝澤賢,小蘇,俞煥,花花的指導~
話不多說,立馬送上小程序碼,大家可以掃碼體驗一下
每日出擊運簽小程序主要劃分為幾個功能模塊:
下面重點介紹一下搖一搖、抽簽并顯示運簽結果、保存圖片三個功能。 關于搖一搖功能 花叔早前已經寫過文章(鏈接如下:http://www.ifanr.com/minapp/880378)介紹過搖一搖的實現思路了,這里簡單歸納一下搖一搖功能的幾個主要的思路。 準備: 需要設置一組變量,保存搖一搖x,y,z三軸的數值,需要設置一個變量來記錄搖一搖的時間。 實現注意事項:
//計算 公式的意思是 單位時間內運動的路程,即為我們想要的速度 var speed = Math.abs(x + y + z - lastX - lastY - lastZ) / diffTime * 10000;
wx.onAccelerometerChange(CALLBACK):用于監聽加速度數據,在發生有加速度的動作的時候,執行搖一搖的判斷邏輯 wx.stopAccelerometer:在搖一搖的邏輯執行期間,需要停止監聽加速度數據,避免多次觸發搖一搖
關于抽簽并顯示運簽結果的功能 每日出擊運簽的小程序其中有一個需求是抽簽并顯示運簽結果。在用戶每天進入小程序的時候,通過搖一搖,得到一個抽簽結果,如圖所示:
關于這塊功能,這里需要著重介紹vine在實現小程序的過程中比較關注的兩個點,一個是隨機顯示抽簽結果,一個是用于顯示簽紙的動畫效果。
隨機出現五個運簽結果,大吉、吉、平、兇、大兇;不同結果對應下面不同文案;每個用戶每天只能獲取同一個結果。隨機文案,每個用戶在用完庫存前不重復 // 打亂數組順序 function shuffle(a) { var j, x, i; for (i = a.length - 1; i > 0; i--) { j = Math.floor(random() * (i + 1)); x = a[i]; a[i] = a[j]; a[j] = x; } } var m_w = 123456789; var m_z = 987654321; var mask = 0xffffffff; function seed(i) { m_w = i; m_z = 987654321; } function random() { m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask; m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask; var result = ((m_z << 16) + m_w) & mask; result /= 4294967296; return result + 0.5; } //獲取用戶id var userid = parseInt(gbConfig.user_id, 16); seed(userid); // 隨機生成抽簽描述 var qian = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]; var result = []; for (var i = 0; i < 10; i++) { shuffle(qian); result = result.concat(qian); } // 隨機生成抽簽結果 var luck = [1, 2, 3, 4, 5]; var luckarr = []; for (var i = 0; i < 60; i++) { shuffle(luck); luckarr = luckarr.concat(luck); }
2.簽紙顯示的動畫效果
在通過減幀以后,得到了8張序列幀圖,vine發現,8張序列幀圖通過拼接得到的雪碧圖會非常大(達到了1M左右的大?。?,所以再次進行減幀得到由4張序列幀圖拼接而成的雪碧圖(也有500+kb左右)。但是在實際放到頁面上面的時候發現,4張序列幀圖幀數太少,造成了動畫卡頓不流暢的情況,而且在低端安卓機上面,這組序列幀動畫完全無法流暢進行。所以第一套方案放棄。 第二:把8張序列幀圖分開加載,4張為一組,拼接成一張雪碧圖,一共兩張雪碧圖,如下:
vine的處理方式是:先加載第一張雪碧圖,在第一張雪碧圖逐幀動畫結束后,切換到第二張雪碧圖,無縫連接播放第二組逐幀動畫。結果在低端安卓機上面出現了同樣的情況,動畫播放非??D,而且在圖片切換的過程中出現了空白。于是第二套方案失敗。 第三:在vine百思不得其解的時候,突然發現,這套序列幀有一個特點:它的簽紙和卷軸并不是立體的!也就是說,這里其實可以不需要序列幀來實現簽紙打開的效果,只需要最后一張圖就可以了:
關于保存圖片的功能
通過點擊分享按鈕,可以生成一張和簽紙類似的圖片,用戶可以長按保存這張圖片到手機本地。從而達到轉發分享的目的。 而這個保存,所需要的就是canvas。小程序API提供了canvas的接口:
通過這個接口,我們可以把當前畫布指定區域的內容導出成指定大小的圖片,然后再調用小程序的預覽接口進行圖片預覽以及保存:
但是在這里,vine遇到了幾個問題:
下面來介紹一下這兩個問題相應的解決措施: 多次點擊保存按鈕觸發canvas,導致手機滑動的時候非常卡頓 canvas只在需要觸發的時候渲染,在用戶沒有點擊保存按鈕的時候,默認不渲染canvas。代碼如下:由于小程序和MVVM框架類似,無法直接操作dom,所以vine采取了在樣式上面添加狀態,通過修改showcanvas變量的值,來控制canvas的顯示和隱藏。在執行畫圖操作的時候使變量值為false,顯示canvas,在繪制完成的時候更改變量值,隱藏canvas <canvas class='{{showcanvas ? "hidcanvas" : "showcanvas"}}' style="width: 750px; height: 1334px;position:fixed;left:100000rpx;top:-100000rpx;" canvas-id="shareQRcode"></canvas>
生成預覽圖片時間非常慢 生成預覽圖片時間非常慢,目前判斷的原因是,直接預覽canvas臨時路徑的圖片耗時比較久。那么應該如何優化這個過程呢? 小程序的API提供了幾個關于文件的接口:
我們可以通過這幾個接口優化目前的預覽方式。在這其中vine做了兩種不同的嘗試。 第一,在執行wx.previewImage的success的回調的時候,把previewImage生成的臨時路徑保存下來,下次再點擊預覽的時候,直接獲取本地已保存的文件列表wx.getSavedFileList,取得最近保存下來的文件的本地路徑,進行預覽。這么做的想法主要是為了解決canvas渲染的問題,每天只渲染一次,后續都是通過預覽本地圖片鏈接達到生成圖片的目的。梳理一下流程: 初次渲染:canvasToTempFilePath -> previewImage -> saveFile 二次渲染:getSavedFileList -> previewImage 可惜理想始終是豐滿的,在實際操作的過程中vine發現,通過這樣的方式預覽圖片的時候,一直處于loading的狀態,無法生成初次渲染的圖片。vine非??鄲?,至今沒能找到原因。 于是vine想了另一種辦法,調整了預覽的順序如下: 初次渲染:canvasToTempFilePath -> saveFile -> previewImage 二次渲染:getSavedFileList -> previewImage 這時候vine發現,先把canvas生成的臨時路徑保存到本地,再預覽,這種方法是可行的!而且在二次渲染的過程中,由于只是讀取小程序本地的圖片路徑,無需再次調用canvas繪圖,二次預覽的時間大大減少。 在這里我們需要注意官方文檔中提到的一點:小程序本地文件存儲的大小限制為10M。所以我們需要調用wx.removeSavedFiled的方法刪除我們不需要的圖片(當天之前存下來的圖片都是我們無需保存到本地的圖片,可以刪除) 三星note5保存圖片尺寸的問題 在數量龐大版本不一的安卓手機上,vine收到反饋,三星note5在保存圖片的時候會遇到圖片底部被裁減的情況。在通過多次修改以及對比類似的小程序以后發現,note5用canvas繪制的圖片有一個最大的范圍是750*1150,超出這個范圍的圖片,底部就會被裁減。為什么會有這個最大范圍vine目前還沒探索出結論,希望遇到過這個問題的大神可以和vine交流一下心得,手動比心!~ 最后梳理一下小程序項目的一些注意點:
|