原創(chuàng)|行業(yè)資訊|編輯:郝浩|2013-09-10 13:50:54.000|閱讀 601 次
概述:通過(guò)PhoneGap應(yīng)用程序文件夾構(gòu)建、觀察屏幕底部的顯示、添加應(yīng)用程序和圖像用到canvas后三步,最終實(shí)現(xiàn)用Javascript和PhoneGap加速計(jì)制作移動(dòng)app。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
當(dāng)Android和iOS平臺(tái)繼續(xù)競(jìng)爭(zhēng)的時(shí)候,允許開(kāi)發(fā)人員構(gòu)建跨平臺(tái)應(yīng)用程序的庫(kù)越發(fā)具有吸引力,其中最為突出的便是PhoneGap庫(kù)。在本教程中,我們將建立一個(gè)硬件感知應(yīng)用程序,用JavaScript 來(lái)處理設(shè)備加速計(jì)。
如果你還沒(méi)有下載最新版的PhoneGap framework,那再簡(jiǎn)單不過(guò),假設(shè)你已經(jīng)安裝了NodeJS。一旦你再裝上PhoneGap,我們便可以創(chuàng)建應(yīng)用程序。
1)通過(guò)輸入如下命令行來(lái)創(chuàng)建PhoneGap應(yīng)用程序。
$ phonegap create accelerate $ cd accelerate $ phonegap local plugin add //git-wip- us.apache.org/repos/asf/cordova-plugin-device-motion.git
注意應(yīng)用程序?qū)⒈粍?chuàng)建在你的命令行中指定的任意文件夾內(nèi),請(qǐng)先確認(rèn)是導(dǎo)向了你的目的文件夾。命令行指令的前兩行是不言自明的,它們創(chuàng)建PhoneGap應(yīng)用程序,調(diào)用加速和導(dǎo)航到剛創(chuàng)建的文件夾。
最新版的PhoneGap使用遠(yuǎn)程插件架構(gòu),因此我們必須用命令行最后一行的的代碼來(lái)手動(dòng)獲取并安裝加速插件。
2)打開(kāi)加速文件夾并注意應(yīng)用程序結(jié)構(gòu)包含一個(gè)www文件夾。我們將在這里開(kāi)展工作。
Figure 1:PhoneGap應(yīng)用程序文件夾構(gòu)建
PhoneGap創(chuàng)建命令實(shí)際上是構(gòu)建了一個(gè)小的示例應(yīng)用程序。如果你加載index.html到一個(gè)瀏覽器,可以看到它的啟動(dòng)畫面。如果你喜歡,可以在移動(dòng)設(shè)備中運(yùn)行整個(gè)應(yīng)用程序。
在Android移動(dòng)設(shè)備上運(yùn)行該示例應(yīng)用程序,用USB數(shù)據(jù)線連接該設(shè)備到你的電腦。發(fā)出如下命令用命令行路徑指向你的項(xiàng)目文件夾:
$ phonegap build android $ phonegap run android
在iOS設(shè)備上運(yùn)行示例應(yīng)用程序,實(shí)際上更復(fù)雜,因?yàn)樵O(shè)備必須通過(guò)XCode被正確的配置。為測(cè)試而配置iOS設(shè)備,你必須用蘋果開(kāi)發(fā)程序注冊(cè)。
我們將從應(yīng)用程序中刪除CSS文件夾,icon.png,圖像文件夾和js文件夾。你可以在你最喜歡的文本編輯器中打開(kāi)index.html,一旦打開(kāi),就移除跟該示例應(yīng)用程序相關(guān)的代碼。然后,還會(huì)剩如下一些東西:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="format-detection" content="telephone=no" /> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" /> <script type="text/javascript" src="phonegap.js"></script> <title>Accelerate</title> </head> <body> </body> </html>
正如你所看見(jiàn)的,有一些元標(biāo)簽在標(biāo)題上,處理屏幕尺寸標(biāo)準(zhǔn)化。其余的代碼是標(biāo)準(zhǔn)HTML。我們將首先設(shè)置一個(gè)初始化程序以便知道設(shè)備和PhoneGap庫(kù)均已準(zhǔn)備好讓我們運(yùn)行任何代碼。
我們將添加如下<script>元素到到文檔中的<head>,在<title>之前。
<script> window.onload = function() { //init(); document.addEventListener("deviceready", init, false); } function init() { alert("Ready!"); } </script>
init()函數(shù)將成為我們進(jìn)入應(yīng)用程序的切入點(diǎn)。你將注意到匿名函數(shù)聯(lián)系著window.onload事件,附加“deviceready”(設(shè)備就緒)監(jiān)聽(tīng)器到程序上。這個(gè)事件將告訴我們?cè)O(shè)備和PhoneGap
庫(kù)何時(shí)就緒以和用戶互動(dòng)。為方便起見(jiàn),我們也可以注釋調(diào)用init()(如果想要測(cè)試瀏覽器),因?yàn)?ldquo;deviceready”事件是PhoneGap庫(kù)的一部分,它不會(huì)在瀏覽器里運(yùn)行。
這是一個(gè)很好的點(diǎn)來(lái)停止和測(cè)試。當(dāng)Android設(shè)備處于連接狀態(tài),命令行指向應(yīng)用程序文件夾發(fā)出如下命令:
$ phonegap run android
如果你得到了預(yù)期的報(bào)警框,并且其它一切都是正確的,則是時(shí)候?yàn)閼?yīng)用程序創(chuàng)建UI了(此刻你也許會(huì)想要在init()函數(shù)注釋報(bào)警框)。我們將創(chuàng)建一個(gè)相當(dāng)簡(jiǎn)單的UI,來(lái)向我們展示設(shè)備中的加速計(jì)生成的結(jié)果。我們將添加如下HTML到body元素內(nèi)。
<footer> <table id="footerTable"> <tr> <td>X: <span id="xOut"></span></td> <td>Y: <span id="yOut"></span></td> <td>Z: <span id="zOut"></span></td> </tr> </table> </footer>
添加一種元素到文檔head以容納CSS:
<style> body { margin: 0px; } #footerTable { width: 100%; } footer { position:absolute; bottom:0; width:100%; height:40px; background:#ccc; } </style>
在PhoneGap庫(kù)中,加速對(duì)象有三種方式,分別是:
第一種方式,getCurrentAcceleration(),將獲取一個(gè)當(dāng)函數(shù)在執(zhí)行時(shí)加速計(jì)讀取的快照。watchAcceleration()將返回加速計(jì)讀取直到clearWatch()命令被發(fā)出。我們將使用watchAcceleration(),以便能在一段時(shí)間內(nèi)看到加速。
watchAcceleration()方式返回一個(gè)ID值,我們稍后使用該值能夠停止加速計(jì)。這點(diǎn)很重要,因?yàn)楫?dāng)不再需要加速計(jì)到時(shí)候,我不能讓加速計(jì)占用有價(jià)值的資源。
編輯你的代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="format-detection" content="telephone=no" /> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" /> <style> body { margin: 0px; } #footerTable { width: 100%; } footer { position:absolute; bottom:0; width:100%; height:40px; background:#ccc; } </style> <script type="text/javascript" src="phonegap.js"></script> <script> var watch = 0; window.onload = function() { //init(); document.addEventListener("deviceready", init, false); } function init() { watch = navigator.accelerometer.watchAcceleration(success, failure, {frequency: 100}); } function success(accel) { document.getElementById("xOut").innerHTML = accel.x; document.getElementById("yOut").innerHTML = accel.y; document.getElementById("zOut").innerHTML = accel.z; } function failure() { alert("Error"); } </script> <title>Hello World</title> </head> <body> <footer> <table id="footerTable"> <tr> <td>X: <span id="xOut">0</span></td> <td>Y: <span id="yOut">0</span></td> <td>Z: <span id="zOut">0</span></td> </tr> </table> </footer> </body> </html>
我們已經(jīng)添加基礎(chǔ)代碼以使得加速計(jì)運(yùn)行。你將注意到init()函數(shù)包含一行非常重要的代碼:
watch = navigator.accelerometer.watchAcceleration(success, failure, {frequency: 100});
這行實(shí)質(zhì)上是配置加速計(jì)并使之運(yùn)轉(zhuǎn)。如果加速計(jì)成功地獲取設(shè)備移動(dòng)信息,watchAcceleration()方式的三個(gè)參數(shù)將發(fā)出call back,反之亦然。一個(gè)頻率對(duì)象用加速計(jì)在毫秒中被取的樣來(lái)設(shè)置頻率。
success()和failure()的收call back該是相當(dāng)直接的。在success()call back中,一個(gè)加速對(duì)象被傳到函數(shù),它包含了讀取x/y/z軸的屬性。failure() call back則是簡(jiǎn)單的輸出一個(gè)錯(cuò)誤信息。
此刻將是有一次測(cè)試你的應(yīng)用程序的好時(shí)機(jī),看看是否一切都工作正常。再一次,構(gòu)建并運(yùn)行你的應(yīng)用程序發(fā)布如下命令:
$ phonegap run android
如果一切工作正常,在移動(dòng)設(shè)備的時(shí)候,你則應(yīng)該在屏幕底部更新看看X/Y/Z的解析。慢慢沿著不同的軸向移動(dòng)設(shè)備,注意X/Y/Z的反映。
Figure 2:注意屏幕底部的顯示。
現(xiàn)在我們將讓應(yīng)用程序變得更有趣一些,用加速計(jì)使對(duì)象繞屏移動(dòng),通過(guò)HTML添加對(duì)象本身,然后用加速計(jì)的讀數(shù)來(lái)決定速率和移動(dòng)方向。作為準(zhǔn)備,我們可以為應(yīng)用程序添加一個(gè)canvas然后將一個(gè)對(duì)象放入其中。為了添加這個(gè)canvas,我們將添加一個(gè)canvas元素到body第一行。
<canvas id="myCanvas" ></canvas>
我們還將標(biāo)準(zhǔn)化HTML和body的寬度、高度和margin css屬性以防萬(wàn)一。添加如下選擇器和規(guī)則到你的CSS。
{ width: 100%; height: 100%; margin: 0px; }
用一張叫做“crosshair.png”的圖像。我們將加載它到canvas在int()事件中。你將要為canvas的context和目標(biāo)設(shè)置cnv,使得圖像作為全局腳本的頂端。
照如下方法修改你的int()函數(shù):
function init() { var iW = window.innerWidth; var iH = window.innerHeight; cnv = document.getElementById('myCanvas').getContext("2d"); cnv.canvas.width = iW; cnv.canvas.height = iH-40; target = new Image(); target.src = "crosshair.png"; target.onload = function() { cnv.drawImage(target, (iW-(target.width))/2, (iH- (target.height))/2); } watch = navigator.accelerometer.watchAcceleration(success, failure, {frequency: 100}); }
這里會(huì)大有文章,iW和iH變量包含屏幕大小。顯然移動(dòng)設(shè)備在它們的不同技術(shù)參數(shù)間變化,因此我們要確保創(chuàng)建的一個(gè)canvas是彈性的。cnv變量用來(lái)引用我們將做大量工作的context對(duì)象。把canvas想作是隱形層將會(huì)很有用。
我們用context對(duì)象、cnv來(lái)設(shè)置canvas的寬高屬性。為顧及我們已經(jīng)在底端顯示中創(chuàng)建的output bar,得從高度中減去40。我們初始化目標(biāo)變量為一個(gè)圖像目標(biāo)并提供源圖像到src屬性。
我們要確保圖像在我們?cè)噲D展示它之前已經(jīng)被加載,因此我們?cè)O(shè)置一個(gè)匿名函數(shù),它在圖像對(duì)象調(diào)用目標(biāo)加載時(shí)被調(diào)用。在那時(shí)我們回執(zhí)圖像并做一些簡(jiǎn)單的數(shù)學(xué)把它放到屏幕中心。最終我們配置了加速計(jì)。
這是又一個(gè)在你的設(shè)備上測(cè)試程序的絕佳時(shí)機(jī)。
Figure 3: canvas后的應(yīng)用程序和圖像已經(jīng)被添加到canvas。
現(xiàn)在,當(dāng)傾斜設(shè)備時(shí),圖像將會(huì)移動(dòng),加速計(jì)做出反應(yīng)。大多數(shù)工作將在success() callback函數(shù)中完成。但是,我們還可以讓init()函數(shù)做一些變化以促成一個(gè)運(yùn)行更順暢的應(yīng)用程序。修改的init()函數(shù)如下:
function init() { var iW = window.innerWidth; var iH = window.innerHeight; canvas= document.getElementById('myCanvas'); cnv = canvas.getContext("2d"); cnv.canvas.width = iW; cnv.canvas.height = iH-40; target = new Image(); target.src = "crosshair.png"; xPos = (iW-target.width)/2; yPos = (iH-target.height)/2; target.onload = function() { cnv.drawImage(target, xPos, yPos); } watch = navigator.accelerometer.watchAcceleration(success, failure, {frequency: 25}); }
打開(kāi)你已經(jīng)修改的init()添加canvas到你的script開(kāi)始時(shí)的全局列表。你還將注意到在init()處理捕捉圖像位置期間,xPos和yPos變量被設(shè)置,你同樣也需要添加他們到全局列表。最后,降低頻率值到25,我們就可以每25毫秒從加速計(jì)獲取結(jié)果。現(xiàn)在到success()callback函數(shù):
function success(accel) { document.getElementById("xOut").innerHTML = accel.x; document.getElementById("yOut").innerHTML = accel.y; document.getElementById("zOut").innerHTML = accel.z; cnv.clearRect(0, 0, canvas.width, canvas.height); xPos += -1*(accel.x * 1.5); yPos += (accel.y * 1.5); cnv.drawImage(target, xPos, yPos); }
更新屏幕底部的顯示欄后,clearRect()方式被canvas對(duì)象移除。這在刷新圖像之前,在更新的位置清理了canvas。clearRect()方式需要一個(gè)啟動(dòng)點(diǎn)和你想要清理的寬高數(shù)據(jù)。我們清理整個(gè)canvas,所以我們提供它的完整寬高。
接下來(lái)我們?cè)谒⑿轮案聏Pos和yPos。必須否定xPos,才能讓圖像按照用戶傾斜移動(dòng)設(shè)備的方向移動(dòng)。xPos和yPos均乘以1.5以便移動(dòng)圖像稍微快些。最后,drawImage()被調(diào)用,是它在新的位置繪制圖像。
再一次測(cè)試你的應(yīng)用程序,它應(yīng)該是沿著設(shè)備傾斜軸而移動(dòng)的。當(dāng)然,為了挑戰(zhàn)自我,你可以創(chuàng)建額外的代碼,防止圖像從邊緣脫落。
如你所見(jiàn),PhoneGap使得進(jìn)入設(shè)備硬件更加容易,就像這加速計(jì),包含在你的基于JavaScript的移動(dòng)應(yīng)用程序。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都控件網(wǎng)