開源跨平臺移動項目Ngui【視圖與佈局系統】

Ngui簡介

這是一個GUI的排版顯示引擎和跨平臺的GUI應用程序開發框架,基於NodeJS/OpenGL,這也是第一個在移動端Android/iOS融合NodeJS的前端GUI項目,至此JavaScript成爲了真正意義上先後端通吃的語言。css

Ngui的目標:在此基礎上開發GUI應用程序可擁有開發WEB應用般簡單與速度同時兼顧Native應用程序的性能與體驗。html

視圖View

在上一篇中我已經爲你們講了Ngui入門,今天我就來介紹ngui的核心部分(視圖與佈局)。前端

[View]爲gui核心部件派生爲[Notification]。
用它來描述屏幕上全部可見的元素,它是全部視圖的基礎類型它也是事件的響應者,這些事件由硬件以及操做系統觸發。詳細的API文檔講你們去這裏查閱。node

下面是ngui如今提供的全部[View]繼承關係圖:
注:帶*號的爲抽象類型或協議沒有構造函數後端

  • [TextFont]*瀏覽器

    • [TextLayout]*
  • [BasicScroll]*
  • [View]框架

    • [Layout]*iphone

      • [Box]*ide

        • [Div]函數

          • [Shadow]
          • [Indep]

            • [LimitIndep]
          • [Limit]
          • [Image]

            • [Video]
          • [SelectPanel]

            • [Scroll]<[BasicScroll]>
            • [Root]
        • [Hybrid]<[TextLayout]>

          • [Button]
          • [Text]

            • [Input]

              • [Textarea]<[BasicScroll]>
      • [Span]<[TextLayout]>

        • [TextNode]
    • [Sprite]
    • [Label]

看到這個繼承關係你們是否是以爲有點複雜了,其實這要與瀏覽器比那真是小巫見大巫,固然那並非我想要的,這一切都是爲了效率。固然爲了效率在功能上確定是要作裁剪的,魚和熊掌不可兼得。

有這麼多視圖它到底能爲咱們作什麼呢?

視圖在廣義功能上劃分有兩類:

  • 非佈局視圖(非[Layout])
  • 佈局視圖([Layout])

非佈局視圖

顧名思義非佈局視圖就是那種不帶佈局功能的視圖,就是你把它的位置固定後,它是不會再受到任何其它視圖元素有影響,除非你再次更改它的位置translate屬性。這種是最快的,由於不須要進行佈局計算。

如今ngui提供的非佈局視圖有兩個:

  • [Sprite]
  • [Label]

關於這兩個視圖的具體API接口說明請你們查閱文檔,但在這裏特別要說明的是transform,也就是矩陣變換。

矩陣變換是GUI繪圖系統裏的一個重要概念,transform用一個Matrix來描述繪圖元素點線或面在屏幕上的實際位置與形狀,這個矩陣一般由一組3x34x4向量組成,3x3爲2d矩陣4x4爲3d矩陣,在[View]上使用的是一個裁剪過的3x2的2d矩陣所它暫時不支持3d中的z軸,之後的版本中能夠會所變化。

[View]中的transform屬性並無直接暴露而是換成了一組屬性:

  • x
  • y
  • scaleX
  • scaleY
  • rotateZ
  • skewX
  • skewY

你能夠經過matrix屬性獲得這個矩陣但它是隻讀的,只能經過xy這個方式對它進行設置。

調用final_matrix()函數獲得的是父視圖的final_matrix與當前視圖的matrix乘積。對這就是這個視圖在屏幕是的真實位置,確切的講是這個[View].origin在屏幕上的確切位置,由於嚴謹的說一張圖片或一個矩形在屏幕上是由4個點組成的一個面。

注意:
頻繁的交替設置transform與調用matrix/finalMatrix會帶來沒必要要的性能消耗,ngui的渲染邏輯是在渲染畫面前不對任何視圖屬性設置作額外的計算只作存儲並該標記屬性的改變,等待準備渲染前才作統一的計算。當一個視圖的transform改變時若是這時你要獲取matrixfinalMatrix那麼直接返回matrixfinalMatrix那必定是不正確的,幸虧系統會作檢測當發生了改變你要強取些值會提早對這些值作運算,返回一個正確的值給你,但若是你頻繁的設置與獲取,那就會頻繁的作些運算。而且這隻僅限於非佈局視圖,在佈局視圖上這樣作並不會返回正確的值參見[Trap in Layout]

佈局視圖

佈局視圖按可放置內容劃分有三類:

  • [Div]
  • [Hybrid]
  • [Span]

Div

從API文檔上看見[Div]只有一個屬性contentAlign, 那麼這裏重點講述就是這個屬性,由於它是與瀏覽器徹底不相同有的地方,至於基礎類型[Box]你們能夠參與API文檔會有詳細說明,注意padding這個屬性在ngui裏是沒有的,由於這個致使系統複雜性上升,但之後要不要加待定。

ngui中[Div]並無本身單獨的浮動方式這個屬性。但[Div]能設置它的contentAlign對它的內容對齊方式作出更改,這個屬性可選的值有4個,默認爲left左對齊

  • left
  • right
  • top
  • bottom

這其實很好理解 :

  • leftright爲水平佈局,內容對齊方式從左到右或從右到左排列,溢出往下換行。
  • topbottom爲垂直佈局,內容對齊方式從上到下或從下到上排列,溢出往右換列。

須要注意的是它的內容必須爲[Box]類型不然這個屬性並不會對它產生任何的效果,若是它內部出現了[Span]或[TextNode]那麼[Span]與[TextNode]的出現不會對[Div]的內容佈局形成任何影響,由於[Div]會忽略非[Box]內容的排版處理,同理一個[Box]或[Div]出如今非排版佈局視圖內部那它的位置與使用非佈局視圖沒有區別。

Hybrid

與[Div]同樣它也只有一個屬性textAlign但它能夠對任何[Layout]內容作排版處理這固然也包括[Span]與[TextNode]。

與[Div]的區別[Hybrid]的內容方式的不一樣,[Hybrid]把它的全部內容都當成文本進行處理。它的可選有6個,默認爲left

  • left
  • right
  • center
  • left_reverse
  • right_reverse
  • center_reverse

left right center 很好理解
left_reverse right_reverse center_reverse 是在對齊的基礎上將內容顛倒排列,

如:對Ngui進行顛倒排版會變成這樣

left_reverse center_reverse right_reverse
SJodacovA SJodacovA SJodacovA

Span,TextNode,Text

  • [Span]並無顯示實體,也就是說它並不會在屏幕上顯示任何可見的東西,它的存在只爲是爲了設置嵌套的[TextNode]視圖屬性,由於以[TextLayout]上的屬性都能被它的子[TextLayout]所繼承,這也是ngui中惟具備繼承性質屬性的視圖。
  • [TextNode]爲[Span]的子類型,但它有實體它也是個葉子視圖,也就是它不能再存在子視圖。
  • [Text]繼承於[Hybrid]與[TextNode]同樣也是葉子視圖不能存在子視圖

Indep

獨立的[Div],至關於html-css中的絕對定位,它存在於[Div]與[Hybrid]內部時,會進行獨立排版,不會影響其它兄弟視圖的排版位置。

Limit,IndepLimit

限制的盒子,minWidth, maxWidth,minHeight,maxHeight,這些屬性能限制盒子的尺寸,這與html中的限制很類似。

Root

[Root]一個應用程序只能是惟一的也是必須的

Examples

最後爲你們寫一段代碼實際運行一下

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的運行效果:

下面是codeiphone6/code的運行效果

下面是Google nexus6的運行效果:

下面是codeGoogle nexus6/code的運行效果


就說到這裏吧,已經累的不行了,下一篇爲你們講動做系統。

謝謝你們,未完待續~

相關文章
相關標籤/搜索