聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

七月 4, 2013

Yuren's Info Area
yurinfore
is about »

tag cloud

» Gaia Development Workflow

這是 Firefox OS - Gaia 開發時的 workflow,沒時間寫文章,先放張圖。


十一月 27, 2012

Yuren's Info Area
yurinfore
is about »

tag cloud

» [Firefox OS] HTML 內嵌 SVG 動畫實例

前言:這些實作都已經包含在最新的 Firefox OS 裡面,有興趣的可以 check 最新的 code 出來玩。

最近接到了一個需要變更設計的 issue,我看到這個設計愣了一下,主要的原因是因為要做出這樣的設計用 HTML + CSS 還真的需要想一下如何實作。

主要更改的地方是 Firefox OS 的兩個元件:Lockscreen 跟 Dialer。

這兩個元件主要的設計概念都是希望有一條像是橡皮筋(或跳繩)的線上下的跳動,並且在往上跳動的時候露出下面的兩個按鈕,提示使用者可以把這條橡皮筋往上滑,接下來按下按鈕解鎖。我們這邊只討論如何實作,不討論視覺設計 :P



如上圖所示,上面的那條弧線是需要動態的上下彈動,如果用 HTML + CSS 的話有幾種方法可以嘗試做到跟缺點:

  1. 上一個 canvas,然後把這條線在 canvas 上面不斷的重繪(缺點:這樣要不停的計算跟重繪)
  2. 用超級多張 png 不停的置換圖檔(缺點:要生出超級多圖)
  3. 先畫一張弧線,接著用 CSS 的 Transform 更改他的 scale()(缺點,接近中間的時候整個圖形就會被壓得很扁)
考慮過 HTML + CSS 的解法之後,以上的解法似乎都不太好。這個時候我就開始考慮用 SVG 來做這件事情。但是用 SVG 來做這件事情其實是蠻冒險的,因為在這期間問了幾個同事他們都沒有測試過 SVG 在 Firefox OS 真正的手機上的詳細效能。所以收到這個設計的時候我先寫信問了個對於整個 platform 比較熟的同事,然後因為 deadline 非常的趕,但是我又不能不確定效能狀況就下手,所以就先決定做個獨立可以同時在電腦跟手機都可以驗證的小型 app。

這個 app 要驗證的事情有兩件:
  1. 當用滑鼠(手指)按住拖曳,這個時候改變 SVG 的屬性讓他改變弧度的效能衝擊有多大
  2. 使用 SVG animation (SMIL) 效能到底如何
然而做這個 DEMO 幾乎也可以搞清楚要怎麼用 SVG 實作這個解鎖畫面了。在弧線的部分,採用 SVG 的 Path 搭配上 c (curveto) 參數可以達成弧線,動畫的部分則是用 SMIL 的 animate tag 完成。下面這個網頁就是驗證效能用的網頁(我只用過 Firefox 打開過,其他瀏覽器不知道有沒有支援):

http://yurenju.github.com/lockscreen-demo/wrapper.html

這邊只是用來驗證的網頁,所以會有一些小 bug。主要的功能就是往上拉的時候用 javascript 去改變 SVG d (data) 裡面的 c (curveto) 的參數,放開滑鼠的時候用 SMIL animate 把 curve 滑回原位。而下面有個連結 install lockscreen demo 用途是如果你用 Firefox OS 的手機點了這個連結就可以把這個 demo app 安裝到手機裡面。

很棒的是當我把這個 app 安裝到手機裡面,發現這樣實作的效能在手機上是完全可以接受的!既然可以接受那就大膽的把這樣的實作方式引入 Firefox OS。這邊有針對 lockscreen 的 commit


在 SVG 方面,首先利用 path tag 來劃出最原始的弧線。在 attribute d (data) 裡面用了兩個參數:M (moveto) 跟 C (curveto),moveto 用來指定 path 的起點,curveto 用來指定用來控制曲線的兩根桿子的弧度。SVG 1.1 Path 裡面有張圖讓 curve 的控制點比較好理解一點:



C 後面接的兩組 (x, y) 分別是兩個控制點的坐標,我們需要的大概像是最左上角那張圖的效果。attribute 'd' 裡面的最後一個參數則是曲線的終點。整個 attribute 長這樣:

M0,80 C100,150 220,150 320,80

第一個是曲線起始坐標,最後一個是曲線結束坐標,中間兩個則是控制點的坐標。

接下來說明 path 裡面的五個 animate tag。1 跟 3 是針對曲線的彎度變化,而 2 跟 4 則是針對透明度的變化。1-4 都是用於拖曳橡皮筋之後放開的動畫,而 (5) 則是當你不去碰橡皮筋時,他的彈跳提示動畫。請想像這一整組動畫:一條繩子彈上去後隨著重力掉下來,掉到地上之後會再彈跳幾下後靜止。下面講解比較複雜的第五組動畫:

先看到 values。用分號切分開來的話總共有五組數據:
  1. 起始的曲線數據 (Y=150)
  2. 第一次彈跳到最高的數據,兩個控制點的 Y 坐標都變少了讓整個圓弧的開口朝下 (Y=40)
  3. 回到最地上 (Y=150)
  4. 再次彈起來,但是幅度較低 (Y=100)
  5. 回到原點 (Y=150)
至於 keySplines 則是指定彈跳的 timing function,如果你用過 CSS animation,就跟 ease-in/out 那種差不多的東西,只是要直接指定數據,下面這張圖是 keySplines 設定 0.5 0 0.5 1 會產生的 timing function:


keySplines 裡面有四組數據,分別就是 1-2, 2-3, 3-4, 4-5 這四段動畫的 timing function。每一組數據裡面都是兩個控制點的坐標。

SVG 的部分大概就是這樣!這部分有很多需要細微調整的,有興趣的就留言一起討論吧。接下來是 Javascript 部分。這邊我就講一些 SVG + Javascript 要注意的小技巧
  • fill=freeze 功能為讓動畫結束之後停留在最後一格,不過這樣的話如果你想要用 mousemove 去逐漸改變曲線的外形時,你會發現這個屬性會讓整個 path 卡死。如果拿掉 fill=freeze 的話,因為我執行完動畫之後還要把曲線固定在最後一格,所以拿掉的話就導致動畫有閃爍的現象。 解法就是平常不用,等到要播放補間動畫的時候再把 freeze 加上去。
  • 用 beginElement(), endElement() 來播放、停止動畫
  • addEventListener endEvent 來處理動畫結束後的後續處理。
這邊的細節真的非常的多,如果你也想 HTML + SVG + Javascript 來實作的話,建議是要讀一下 SVG 跟 SMIL 的 spec,然後撿想要用的東西放在裡面,什麼不明白的事情就直接寫到 SVG 裡面看一下效果如何就是了。那個時候這個 commit 要上真是超級緊張的,因為這是我開始 contribute Firefox OS 以來最大的修改。結果上的時候還是有些小細節沒注意到,感謝同事的幫忙在 bug 還沒關之前就注意到這個低級錯誤然後讓我可以及時的推入 repository 了。

之後更複雜的是 Dialer 的部分。



如上圖所見左右兩邊各有一個會隨著弧線移動的兩個 spotlight,而線段上的顏色還多了紅色跟綠色線段。線段不同顏色方面,看遍了 SVG 的資料後比較方便的方法還是用多重的漸層並且把兩個漸層的 offset 設定成一樣,這樣就可以讓曲線有不同的顏色。至於隨著 curve 的 spotlight 則是透過 clipPath 作修剪遮罩,讓漸層只在部分的地方露出來即可。做完這次的 commit 我的 SVG 功力真的大增啊... Orz



這是在 Dialer 曲線用的漸層。2 跟 3 的 offset 都是一樣的,但是顏色卻用不一樣,這樣的技巧可以讓線段不會產生漸層。

這段是如何產生 spotlight 的方法。首先 path 不一樣的地方是 d 除了原本的 M 跟 C 以外,又加了 H V Z 分別用來畫出橫線、直線跟關閉 path 用。fill style 則套用上面的 #gradient-red 的漸層紅色,最後用 clipPath 的方式作剪裁遮罩。對綠色的部分也用相同的方法,最後通通拿去做動畫,就完成啦!

所以這是最後的結果:



Dialer 最後實作的結果在這邊,很可惜速度上並不是很好,目前看起來撥電話進來之後整隻手機的效率會下降許多,目前我們也正在改進這個問題。



這個 lockscreen 的 code 都在 github 上面,有興趣的可以抓下來玩玩 :-)

    十月 15, 2012

    Yuren's Info Area
    yurinfore
    is about »

    tag cloud

    » [Firefox OS] 呼叫 MozActivity 的內部訊息流程

    上週快結束的時候我一直在追蹤一個 Firefox OS 的 Bug #800169,後來發現不是 Gaia (Firefox OS 的 App 層) 之後,我就一路往下看到了 Gecko (Firefox OS 的 Runtime 層),當我覺得快要找出癥結的時候,這個 Bug 在 Nightly build 被別人解決了! XDD

    不過趁著這個機會也把架構熟悉過了一遍,跟大家分享一下。

    先解釋一下這個 bug,Firefox OS 的瀏覽器在把一個網頁加入到 home screen 的時候,加入 Home screen 的確認視窗會跳出來兩次。

    首先我們就從 Browser 的 browser.js 開始,按下『加入至 home screen』後會使用下面的 API 呼叫加入 home screen 的 dialog 。

    new MozActivity({
    name: 'save-bookmark',
    data: {
    type: 'url',
    url: this.currentTab.url,
    name: this.currentTab.title,
    icon: place.iconUri
    }
    });

    MozActivity 是怎麼呼叫 Dialog 的呢?經過追蹤,當你呼叫了 MozActivity 的時候,真正執行的是 B2G/gecko/dom/activities/src/Activity.cpp。當你找出這個地方後可以用 gdb 來確認是不是這裡,詳細的用法可以參考 Debugging B2G using gdb。Activity:Initialize 的最後面的程式碼是這樣:

    nsresult rv;
    mProxy = do_CreateInstance("@mozilla.org/dom/activities/proxy;1", &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    mProxy->StartActivity(this, options, window);
    return NS_OK;

    事實上這個時候 B2G 去調用了同一個目錄底下的 ActivityProxy.js,這個時候用 Child Process Message Manager 的  sendAsyncMessage 丟了用來開啟 Activity 的訊息出去。

    cpmm.sendAsyncMessage("Activity:Start", { id: this.id, options: aOptions });
    cpmm.addMessageListener("Activity:FireSuccess", this);
    cpmm.addMessageListener("Activity:FireError", this);

    ActivityService.jsm 的 receiveMessage 會接收到這個訊息,並且交由 this.startActivity 來處理之。而 startActivity 決定完成要用哪個 app 開啟這個 Activity 後,再用 system-message-internal 的 sendMessage 丟出一個名為 activity 的訊息。

    let sysmm = Cc["@mozilla.org/system-message-internal;1"]
    .getService(Ci.nsISystemMessagesInternal);
    if (!sysmm) {
    // System message is not present, what should we do?
    return;
    }

    debug("Sending system message...");
    let result = aResults.options[aChoice];
    sysmm.sendMessage("activity", {
    "id": aMsg.id,
    "payload": aMsg.options,
    "target": result.description
    },
    Services.io.newURI(result.description.href, null, null),
    Services.io.newURI(result.manifest, null, null));

    最後到了 SystemMessageInternal.js 裡面的 sendMessage 最後會調用 _processPage 來開啟正確的 App。

    let page = { uri: aPage.uri,
    manifest: aPage.manifest,
    type: aPage.type,
    target: aMessage.target };
    debug("Asking to open " + JSON.stringify(page));
    Services.obs.notifyObservers(this, "system-messages-open-app", JSON.stringify(page));

    而追蹤的 bug 的問題點就在這裡,這邊有兩個 match 的 page,所以他連續開啟了兩次 add to home screen 的 dialog。當我追蹤到這邊的時候,其實基本上已經找到問題的根源了。不過在跟別人討論的過程中突然發現有另外一個 bug 的 patch 已經解決這個問題,而且在 nightly 的 build 也不會有這個問題,所以我就沒繼續追蹤下去了。

    藉由這次機會也從 Gaia 到 Gecko 看了一大圈,也算是很有收穫  :D

    五月 21, 2012

    小惡魔AppleBOY
    AppleBOY
    小惡魔 – 電腦技術 – 工作筆記 – AppleBOY is about »

    tag cloud

    » 台灣第一屆 JavaScript Conference Developer 會議

    JSDC 2012

    自從去年辦了台灣第一屆 2011 PHP Conference,2012年開始又來新的第一屆 Javascript Conference,在去年的 PHP 會議由於第一次開始舉辦 PHP Conference,所以比較少人投稿,導致議程裡面出現很多 Javascript 議題,這也是很多朋友的疑問 XD。底下來回顧 JSDC 5/19 (六) 個人參加的議程。由於早上差不多10點半才到,所以前兩場議程(Key Note – Ericsk, Node.JS on Windows Azure)就沒有聽到了,比較可惜。如果沒去聽現場的,可以到官方網站下載投影片參考。

    Key Note – Andreas Gal

    這場最主要是介紹 Mozilla B2G Project,這是去年 Mozilla 的計畫,也在今年二月發表一些 demo 範例,以前程式設計師開發 Mobile device 需要用到大量的 Native API,現在可以利用 HTML5 + Javascript 開發任何驚人的 Application,大家可以在 Github 找到此專案 Gaia,另外可以參考 Boot to Gecko Wiki,現場有 Demo 手機可以玩看看。

    JavaScript在Big Data方面的應用

    這場其實就是推廣 Windows Azure 一些功能還有用 Javascript 處理大量資料,Map Reduce 的 work flow,投影片可以參考這裡,個人對於 Windows 系列的產品沒有很大的興趣,結論就是只有網站夠大才需要考慮到這些應用,不然一般的架構就可以做完了。

    JavaScript MVC compare

    這場是由 TonyQ 主講,相信大家對於他已經很熟悉,在台北每個禮拜都有舉辦 Javascript 小聚會,可以參考 Facebook javascript.tw Group,這場介紹如何選擇一套 Javascript Framework,現場也提到如果想玩新的 Framework,請由全新專案開始,不要拿舊有的網站來開刀,那會是拿石頭丟自己的腳,以老闆角度來想,為啥要導入新的架構,除非你有很大的說服力,不然請打消這個念頭,此主題有提到 AngularJSBackbone.jsSpineJavaScript MVC,講者提到下面幾個重點,對於找一套好的 Framework 非常有幫助:

    • Project Dependency
    • Dependency Management
    • Model-View-Controll structure
    • Entry point
    • Testing

    Project Dependency:
    首先在用任何一套 JS Framework 之前,必需要先瞭解此套件的相依性,例如 Spine.js 需要 include jQueryzepto,另外還需要 CoffeeScript。那 Backbone.js 呢?就需要 include underscore.js 跟 jQuery,所以每一套 Framework 都要瞭解相依性,以及自己撰寫開發的 script 是否可以相依並存,這點是非常重要。

    Dependency Management:
    如何解決相依性管理,這點是就是要瞭解這些 Framework 如何整合而外的 Library,像是 Backbone.js 用了 AMD (Asynchronous Module Definitions) 架構,要瞭解管理這些額外套件,以及整合各大 opensource 架構,例如 Require.js

    Entry Point:
    各大 JS Framework 的主要特性,當您選一套喜歡的 Framework,一定會有您自己心目中想要的架構,才會繼續使用它吧,這點大家都必須要先清楚知道,而不是大家用,您就用。像 Sencha Touch,它就是 script base,你只要會寫 javascript 就可以了,不用理會 html dom 元件如何產生出來,因為在 Sencha 底層就幫忙把 Html Layout 處理完畢。Backbone.js 呢,它提供了 URL Routing 功能,這點非常方便,讓後專程式設計師可以專心寫 API,輸出 JSON 格式就可以了。AngularJS 就是以 html 當作 Base,利用 ng-* 插入到 html tag 來產生前端效果。

    Model-View-Controler:
    我想大家一定聽過很多 MVC Framework,像是 CodeIgniter, Django, Yii, Zend Framework …等太多了,那前端的 MVC 呢?這是大家很少注意,也很少使用的地方,個人認為要選擇一套前端 MVC Framework 必須包含 Controller,利用 URL Routing 功能來達到 JS File 的分離,Model 用來連接後端 API,View 則是 Template Engines,以及可以自訂各種不同的 Event。

    Testing:
    前端的 Testing 就看專案需求了,這部份就不多寫了,可以參考 QUnit

    Introducing Mojito

    這場由 Yahoo 前端工程師 David Shariff 來介紹 Mojito MVC application framework,現在前端工程師非常辛苦,因為有太多的 Device 要支援: Android, iPhone, iPad, Windows Phone, other Device…等,每個 Application 用到不同的 Language,每出一個產品,前端做到死,所以 Yahoo 提出了解決方案: Cocktails Mojito。Mojito 實現一種 Language base,支援各式不同的 Devices,包涵各種不同的 Screen Size。Mojito 語言就是 JavaScript,Client, Server 全部都是。大家可以到 Yahoo Github 找到完整 Source Code。Mojito 整合了 YUI3Node.js 當作伺服器端。個人覺得這套好用的原因在於架構清楚,並且幫忙分離檔案目錄結構,這樣對於共同開發團隊非常有幫助。

    Noder eyes for frontend guys

    這場由 Fillano 主講,主要是給大家一堆寫 Node.js 之前所需要的 Javascript 知識,像是單一執行緒,或者是會碰到 async mode,以上都是寫 JS 的工程師會遇到的,投影片值得一看再看,請參考此下載連結

    Non-MVC Web Framework

    永遠的大四生 Fred 所講的一套 MVC Web Framework,base on node.js,講者提到台北一堆神人都自己寫一套 Framework,所以講者也自己創了一套 XD,原本是 RedTea (淡定紅茶 Framework),後來作者把 Express Framewrok 導入,讓開發者更趨向於使用 Express Framework,並且結合 RedTea 所有功能,衍生出另外一套 Kamalan Web Framework 詳細可以參考作者 blog: 【JSDC.tw 2012 簡報檔釋出】Non-MVC Web Framework

    Refactoring with Backbone.js

    Jace Ju 主講,如何幫網站擦屁股,這是我這次去會議看到最多程式碼的一個 Section,主要是把網站本身的 jQuery 程式碼重構成 Backbone.js,對於新人來說是非常好的學習,大家可以看看簡報檔,裡面有講者一步一步詳細分析該如何重構整個 Javascript,完整的把 Backbone.js 導入到開發專案,相信看完此 Slide,會有更多人投入 Backbone.js。

    心得

    個人蠻喜歡參加這種大型會議,可以學習到不同的架構,聽到不同的心得,以及瞭解目前大家開發主流的工具及語言,希望下次能有機會可以分享自己的心得 XD。

    Related View

    support:

    biggo.com.tw

    A Django site.