這是一個GUI的排版顯示引擎和跨平臺的GUI應(yīng)用程序開發(fā)框架,基于NodeJS/OpenGL,這也是第一個在移動端Android/iOS融合NodeJS的前端GUI項目,至此JavaScript成為了真正意義上前后端通吃的語言。
Ngui的目標(biāo):在此基礎(chǔ)上開發(fā)GUI應(yīng)用程序可擁有開發(fā)WEB應(yīng)用般簡單與速度同時兼顧Native應(yīng)用程序的性能與體驗。
在上一篇中我已經(jīng)為大家講了Ngui入門
,今天我就來介紹ngui
的核心部分(視圖與布局)。
View為gui
核心部件派生為Notification。
用它來描述屏幕上所有可見的元素,它是所有視圖的基礎(chǔ)類型它也是事件的響應(yīng)者,這些事件由硬件以及操作系統(tǒng)觸發(fā)。詳細的API文檔講大家去這里
查閱。
下面是ngui
現(xiàn)在提供的所有View繼承關(guān)系圖:
注:帶*
號的為抽象類型或協(xié)議沒有構(gòu)造函數(shù)
看到這個繼承關(guān)系大家是不是覺得有點復(fù)雜了,其實這要與瀏覽器比那真是小巫見大巫,當(dāng)然那并不是我想要的,這一切都是為了效率。當(dāng)然為了效率在功能上肯定是要做裁剪的,魚和熊掌不可兼得。
有這么多視圖它到底能為我們做什么呢?
視圖在廣義功能上劃分有兩類:
顧名思義非布局視圖就是那種不帶布局功能的視圖,就是你把它的位置固定后,它是不會再受到任何其它視圖元素有影響,除非你再次更改它的位置translate
屬性。這種是最快的,因為不需要進行布局計算。
現(xiàn)在ngui
提供的非布局視圖有兩個:
關(guān)于這兩個視圖的具體API接口說明請大家查閱文檔,但在這里特別要說明的是transform
,也就是矩陣變換。
矩陣變換是GUI繪圖系統(tǒng)里的一個重要概念,transform
用一個Matrix
來描述繪圖元素點線或面在屏幕上的實際位置與形狀,這個矩陣通常由一組3x3
或4x4
向量組成,3x3
為2d矩陣4x4
為3d矩陣,在View上使用的是一個裁剪過的3x2
的2d矩陣所它暫時不支持3d中的z軸,以后的版本中可以會所變化。
View中的transform
屬性并沒有直接暴露而是換成了一組屬性:
你可以通過matrix
屬性得到這個矩陣但它是只讀的,只能通過x
與y
這個方式對它進行設(shè)置。
調(diào)用final_matrix()函數(shù)得到的是父視圖的final_matrix
與當(dāng)前視圖的matrix
乘積。對這就是這個視圖在屏幕是的真實位置,確切的講是這個View.origin在屏幕上的確切位置,因為嚴(yán)謹?shù)恼f一張圖片或一個矩形在屏幕上是由4個點組成的一個面。
注意:
頻繁的交替設(shè)置transform
與調(diào)用matrix
/finalMatrix
會帶來不必要的性能消耗,ngui
的渲染邏輯是在渲染畫面前不對任何視圖屬性設(shè)置做額外的計算只做存儲并該標(biāo)記屬性的改變,等待準(zhǔn)備渲染前才做統(tǒng)一的計算。當(dāng)一個視圖的transform
改變時如果這時你要獲取matrix
與finalMatrix
那么直接返回matrix
或finalMatrix
那一定是不正確的,幸好系統(tǒng)會做檢測當(dāng)發(fā)生了改變你要強取些值會提前對這些值做運算,返回一個正確的值給你,但如果你頻繁的設(shè)置與獲取,那就會頻繁的做些運算。并且這只僅限于非布局視圖,在布局視圖上這樣做并不會返回正確的值參見Trap in Layout
布局視圖按可放置內(nèi)容劃分有三類:
從API文檔上看見Div只有一個屬性contentAlign
, 那么這里重點講述就是這個屬性,因為它是與瀏覽器完全不相同有的地方,至于基礎(chǔ)類型Box大家可以參與API文檔會有詳細說明,注意padding
這個屬性在ngui
里是沒有的,因為這個導(dǎo)致系統(tǒng)復(fù)雜性上升,但以后要不要加待定。
在ngui
中Div并沒有自己單獨的浮動方式這個屬性。但Div能設(shè)置它的contentAlign
對它的內(nèi)容對齊方式做出更改,這個屬性可選的值有4個,默認為left
左對齊
這其實很好理解 :
left
與right
為水平布局,內(nèi)容對齊方式從左到右或從右到左排列,溢出往下?lián)Q行。top
與bottom
為垂直布局,內(nèi)容對齊方式從上到下或從下到上排列,溢出往右換列。需要注意的是它的內(nèi)容必須為Box類型否則這個屬性并不會對它產(chǎn)生任何的效果,如果它內(nèi)部出現(xiàn)了Span或TextNode那么Span與TextNode的出現(xiàn)不會對Div的內(nèi)容布局造成任何影響,因為Div會忽略非Box內(nèi)容的排版處理,同理一個Box或Div出現(xiàn)在非排版布局視圖內(nèi)部那它的位置與使用非布局視圖沒有區(qū)別。
與Div一樣它也只有一個屬性textAlign
但它可以對任何Layout內(nèi)容做排版處理這當(dāng)然也包括Span與TextNode。
與Div的區(qū)別Hybrid的內(nèi)容方式的不同,Hybrid把它的所有內(nèi)容都當(dāng)成文本進行處理。它的可選有6個,默認為left
left
right
center
很好理解
left_reverse
right_reverse
center_reverse
是在對齊的基礎(chǔ)上將內(nèi)容顛倒排列,
如:對Ngui
進行顛倒排版會變成這樣
left_reverse | center_reverse | right_reverse |
---|---|---|
SJodacovA | SJodacovA | SJodacovA |
ngui
中唯具有繼承性質(zhì)屬性的視圖。獨立的Div,相當(dāng)于html-css中的絕對定位,它存在于Div與Hybrid內(nèi)部時,會進行獨立排版,不會影響其它兄弟視圖的排版位置。
限制的盒子,minWidth, maxWidth,minHeight,maxHeight,這些屬性能限制盒子的尺寸,這與html中的限制很相似。
Root一個應(yīng)用程序只能是唯一的也是必須的
最后為大家寫一段代碼實際運行一下
import {
GUIApplication: App, Root,
Div,
Indep,
Hybrid,
Span,
TextNode,
} from 'ngui'
new App().start(
<Root>
<Div margin=20 width="full" height=100
backgroundColor="#f00">
<Indep width=50 height=50
backgroundColor="#f0f"
alignX="center"
alignY="center" />
<Div width=50 height="50"
backgroundColor="#00f" />
</Div>
<Hybrid margin=20 width="full" height=100
backgroundColor="#f00" textColor="#ff0"
textBackgroundColor="#00f6">
Hello
<TextNode textColor="#000">
Ngui!
</TextNode>
</Hybrid>
<Hybrid margin=20 width="full" height=100
backgroundColor="#f00"
textAlign="center_reverse">
Hello Ngui!
</Hybrid>
</Root>
)
下面是iphone6
的運行效果:
下面是Google nexus6
的運行效果:
就說到這里吧,已經(jīng)累的不行了,下一篇為大家講動作系統(tǒng)。
謝謝大家,未完待續(xù)~
更多建議: