html5/haXe开发偶感今年上半年开发了一款Flash电子杂志应用,承蒙老客户厚爱,又让我开发 html5 版的电子杂志应用。选择了haXe作为开发语言,磕磕绊绊的,也还算顺利,本文随感而发。 1. 使用haXe开发web app可以提高开发效率。haXe是一种OO语言,可以使用命名空间、封装、继承、事件等熟悉的技巧来辅助开发,haXe会把它翻译成 javascript。haXe支持强类型,熟悉haXe之后,开发速度会很快。强烈推荐各位试用haXe。haXe的简介可以参见我之前的博文:《html5 canvas 版 hello world! 暨haXe简介》和《拥抱haXe之javascript 也玩mvc》。Google的Dart要做的事情,大部分功能,haXe在几年前就已经搞定了。 整个项目:
下面以 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并没有给我带来任何的困难和阻扰。所有的困难和阻扰都来自对html5、ios和haXe的不熟悉。 下面总结一下使用haXe的好处(haXe的缺点和不足将在后文详述): (1)旧有知识可以全部利用上:类、命名空间、继承、重载、默认参数、事件、回调函数、泛型、动态类等都有。此外,还有:宏、内联……; (2)由于支持强类型,IDE的提示很不错;同时由于类型检查机制的存在,可以避免大量的错误; (3)有时候,所想要的类型没有定义,如果不想定义,可以直接使用动态类,动态类的存在,让和html和js打交道非常爽; (4)强悍的 typedef 机制。碰见哪个类型不支持或者定义不完全,typedef一下就够了 2. Canvas APICanvas API,使用中,发现了它的一些坑爹之处。 (1)兼容性问题。某些操作,可能在桌面的 safari上可以顺利运行,但在ipad上就无法运行。 (2)性能。Canvas API的性能是惨不忍睹,据说只有IE9中的Canvas是硬件加速的,因此,如果想以传统的帧动画的模式来开发应用,性能表现会非常差。1000×1000像素左右的图,如果用到缩放,在ipad上,目测也就是5-10fps左右。我最开始用的jeash,是一款在Canvas API基础上的Flash模拟,结果只能到1-2fps。 对于复杂点的应用来说,必须精细的处理Draw API和绘制状态。为了在平板电脑上得到流畅的结果,我自己设计了这样一套绘制机制: 绘制的单元是页。每页为一张图像。用 DrawParams 类来描述绘制参数: 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代表在图像中的待绘制区(x,y,width,height),dx,dy,dw,dh代表在Canvas上的绘制区。这个参数就代表把待绘制区的内容绘制到绘制区。每页有图像和该页的绘制参数。BookContext类管理需要绘制的Page和它的绘制参数。当需要绘制时(初始加载,翻页动画……),更新BookContext的内容,更新绘制参数,进行绘制。 3. localStorage 非常有用localStorage 对于保持页面间的状态非常有用。比如,当横屏转为竖屏时,当缩放页面时,将先前的状态存入 localStorage ,新页面读取localStorage,更正自己的状态,再把 localStorage 清空。 4. 吐槽ipad(1)没有双击事件,没办法,用touchstart来模拟,当两次touchstart间隔在300毫秒内,认为是一次双击; (2)不能通过js来focus某个输入框,无解。 5. 吐槽haXe(1)没有protected; (2)Float,Int是对象,默认值是null!如果不让它是null,必须在构造函数里赋值; (3)闭包比较弱,只认局部变量。 (4)缺乏好的IDE。目前最好用的haXe IDE算是FlashDevelop。 作者:xiaotie , 集异璧实验室(GEBLAB)
若标题中有“转载”字样,则本文版权归原作者所有。若无转载字样,本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. |
|