今年上半年開發(fā)了一款Flash電子雜志應用,承蒙老客戶厚愛,又讓我開發(fā) html5 版的電子雜志應用。選擇了haXe作為開發(fā)語言,磕磕絆絆的,也還算順利,本文隨感而發(fā)。
1. 使用haXe開發(fā)web app可以提高開發(fā)效率。
haXe是一種OO語言,可以使用命名空間、封裝、繼承、事件等熟悉的技巧來輔助開發(fā),haXe會把它翻譯成 javascript。haXe支持強類型,熟悉haXe之后,開發(fā)速度會很快。強烈推薦各位試用haXe。haXe的簡介可以參見我之前的博文:《html5 canvas 版 hello world! 暨haXe簡介》和《擁抱haXe之javascript 也玩mvc》。Google的Dart要做的事情,大部分功能,haXe在幾年前就已經(jīng)搞定了。
整個項目:
下面以 Book類 為例子,看看haXe會把它翻譯成什么樣子:
haXe 代碼:
1 package core;
2
3 class Book
4 {
5 public var pages:Array<Page>;
6 public var hotlinks:Array<HotLink>;
7 public var pageWidth:Float;
8 public var pageHeight:Float;
9 public var logoUrl:String;
10 public var logoHref:String;
11 public var bookId:String;
12 public var bookTitle:String;
13
14 public function new()
15 {
16 pages = new Array<Page>();
17 hotlinks = new Array<HotLink>();
18 bookId = "";
19 bookTitle = "";
20 }
21
22 public function preloadPages(num:Int):Void
23 {
24 if (num == null) num = 0;
25
26 if (num < 0 || num >pages.length -1) return;
27 var p:Array<Int> = [];
28 p.push(num);
29 p.push(num + 1);
30 p.push(num - 1);
31 p.push(num + 2);
32 p.push(num - 2);
33 p.push(num + 3);
34 p.push(num - 3);
35 p.push(num + 4);
36 p.push(num + 5);
37 for (i in 0 ... p.length)
38 {
39 var index:Int = p[i];
40 if (index >= 0 && index < pages.length)
41 {
42 var page:Page = this.pages[index];
43 page.getImagePage();
44 }
45 }
46 }
47 }
Js 代碼:
1 core.Book = function(p) { if( p === $_ ) return; {
2 this.pages = new Array();
3 this.hotlinks = new Array();
4 this.bookId = "";
5 this.bookTitle = "";
6 }}
7 core.Book.__name__ = ["core","Book"];
8 core.Book.prototype.pages = null;
9 core.Book.prototype.hotlinks = null;
10 core.Book.prototype.pageWidth = null;
11 core.Book.prototype.pageHeight = null;
12 core.Book.prototype.logoUrl = null;
13 core.Book.prototype.logoHref = null;
14 core.Book.prototype.bookId = null;
15 core.Book.prototype.bookTitle = null;
16 core.Book.prototype.preloadPages = function(num) {
17 if(num == null) num = 0;
18 if(num < 0 || num > this.pages.length - 1) return;
19 var p = [];
20 p.push(num);
21 p.push(num + 1);
22 p.push(num - 1);
23 p.push(num + 2);
24 p.push(num - 2);
25 p.push(num + 3);
26 p.push(num - 3);
27 p.push(num + 4);
28 p.push(num + 5);
29 {
30 var _g1 = 0, _g = p.length;
31 while(_g1 < _g) {
32 var i = _g1++;
33 var index = p[i];
34 if(index >= 0 && index < this.pages.length) {
35 var page = this.pages[index];
36 page.getImagePage();
37 }
38 }
39 }
40 }
41 core.Book.prototype.__class__ = core.Book;
js 的prototype我是一竅不通,但這并不影響用haXe寫js程序,這個項目過程中,不熟悉js并沒有給我?guī)砣魏蔚睦щy和阻擾。所有的困難和阻擾都來自對html5、ios和haXe的不熟悉。
下面總結(jié)一下使用haXe的好處(haXe的缺點和不足將在后文詳述):
(1)舊有知識可以全部利用上:類、命名空間、繼承、重載、默認參數(shù)、事件、回調(diào)函數(shù)、泛型、動態(tài)類等都有。此外,還有:宏、內(nèi)聯(lián)……;
(2)由于支持強類型,IDE的提示很不錯;同時由于類型檢查機制的存在,可以避免大量的錯誤;
(3)有時候,所想要的類型沒有定義,如果不想定義,可以直接使用動態(tài)類,動態(tài)類的存在,讓和html和js打交道非常爽;
(4)強悍的 typedef 機制。碰見哪個類型不支持或者定義不完全,typedef一下就夠了
2. Canvas API
Canvas API,使用中,發(fā)現(xiàn)了它的一些坑爹之處。
(1)兼容性問題。某些操作,可能在桌面的 safari上可以順利運行,但在ipad上就無法運行。
(2)性能。Canvas API的性能是慘不忍睹,據(jù)說只有IE9中的Canvas是硬件加速的,因此,如果想以傳統(tǒng)的幀動畫的模式來開發(fā)應用,性能表現(xiàn)會非常差。1000×1000像素左右的圖,如果用到縮放,在ipad上,目測也就是5-10fps左右。我最開始用的jeash,是一款在Canvas API基礎(chǔ)上的Flash模擬,結(jié)果只能到1-2fps。
對于復雜點的應用來說,必須精細的處理Draw API和繪制狀態(tài)。為了在平板電腦上得到流暢的結(jié)果,我自己設(shè)計了這樣一套繪制機制:
繪制的單元是頁。每頁為一張圖像。用 DrawParams 類來描述繪制參數(shù):
1 class DrawParams
2 {
3 public var sx:Float;
4 public var sy:Float;
5 public var sw:Float;
6 public var sh:Float;
7 public var dx:Float;
8 public var dy:Float;
9 public var dw:Float;
10 public var dh:Float;
11 }
sx,sy,sw,sh代表在圖像中的待繪制區(qū)(x,y,width,height),dx,dy,dw,dh代表在Canvas上的繪制區(qū)。這個參數(shù)就代表把待繪制區(qū)的內(nèi)容繪制到繪制區(qū)。每頁有圖像和該頁的繪制參數(shù)。BookContext類管理需要繪制的Page和它的繪制參數(shù)。當需要繪制時(初始加載,翻頁動畫……),更新BookContext的內(nèi)容,更新繪制參數(shù),進行繪制。
3. localStorage 非常有用
localStorage 對于保持頁面間的狀態(tài)非常有用。比如,當橫屏轉(zhuǎn)為豎屏時,當縮放頁面時,將先前的狀態(tài)存入 localStorage ,新頁面讀取localStorage,更正自己的狀態(tài),再把 localStorage 清空。
4. 吐槽ipad
(1)沒有雙擊事件,沒辦法,用touchstart來模擬,當兩次touchstart間隔在300毫秒內(nèi),認為是一次雙擊;
(2)不能通過js來focus某個輸入框,無解。
5. 吐槽haXe
(1)沒有protected;
(2)Float,Int是對象,默認值是null!如果不讓它是null,必須在構(gòu)造函數(shù)里賦值;
(3)閉包比較弱,只認局部變量。
(4)缺乏好的IDE。目前最好用的haXe IDE算是FlashDevelop。