【翻譯】使用Sencha Ext JS創建美麗的圖畫(1)

原文:Creating Beautiful Drawings Using Sencha Ext JS – Part 1

許多人可能對Ext JS中的圖表包相當熟悉了。通過它可以快速創建相當強悍的可視化效果,如三維柱形圖和三維餅圖。通常情況下,對於應用程序來說,單單圖表是不足夠的,例如,想在應用程序中創建流程圖、座位圖、原理圖,又或許是一些交互的動畫等等。

當然,這可通過HTML的Canvas或SVG來直接創建,但這些東西在不支持的平臺上經常會出現問題。要處理跨瀏覽器問題、不同的規則和視網膜顯 示差異以及動畫等等,不是件容易的事情。或許可以使用支持多渲染和提供一些有用的抽象的第三方的庫來解決,但很快你就會發現需要花費不少時間來整合這些 庫。

Ext JS圖表附帶的繪圖包,就可以用來創建任意圖形和動畫,而無須關心瀏覽器使用那種特定技術來呈現圖像,它會根據瀏覽器自動選擇最適合的渲染器 (Canvas、SVG或VML)。在頂層,繪圖包會把HTML5的Canvas作爲底層的API模型。如果要求的是SVG或VML這些引 擎,Canvas API會自動將渲染器轉換爲SVG或VML。

在本系列文章,將學習Sencha圖表所附帶的繪圖包的幾個功能,兵延時如何去使用它們,這樣,就不需要去處理跨瀏覽器兼容這些問題了。

一個簡單的子畫面(Sprite)

子畫面是用來繪製圖形對象的基本元素。通過合併多個子畫面就可以創建出所需的圖像。在圖像包中有許多不同種類的子畫面,每一個子畫面會有不同的屬性,用來定義子畫面的顯示效果,例如,以下就是一個矩形的子畫面:

{    xtype: 'draw',
    width: 250,
    height: 250,
    sprites: [{
        type: 'rect',
        x: 50,
        y: 50,
        width: 100,
        height: 100,
        lineWidth: 4,
        strokeStyle: 'green',
        fillStyle: 'yellow'
    }]
}

演示

以上代碼中,type中的rect對應的是子畫面的別名,而其他的配置屬性就是子畫面的屬性。要注意的是,子畫面屬性不是配置項,在後面的內容,會發現更多有關子畫面屬性與配置項之間的區別。現在,來說說他們在被處理時與使用時的區別。

繪圖容器

在以上示例中xtype爲draw意味着使用的是Ext.draw.Container類。這是繪圖畫面(draw surfaces,Ext.draw.Surface的實例)的容器,用來渲染子畫面的。

要注意的是,在繪圖容器裏用來添加矩形子畫面的是sprites配置項,而不是items配置項。這是因爲繪圖畫面的子組件是畫面,而且在 sprites中定義的子畫面會渲染到默認的主畫面。如果使用子畫面的surface配置項(是的,這不是屬性),就可以將一個子畫面渲染到默認主畫面之 外的畫面,例如:

{
    type: 'rect',
    surface: 'privateSurface',
    x: 50,
    y: 50,
    width: 100,
    height: 100,    ...}

以上代碼將創建一個id爲privateSurface的畫面,而且矩形子畫面將會渲染在該畫面上,而不是默認的主畫面上。配置項surface也可以是一個實際的畫面實例,這意味着子畫面會在繪圖容器實例化後,將使用setSprites方法來添加子畫面。

要注意的是,setSprites方法不會移除已經通過子畫面初始配置或調用setSprites方法添加到畫面上的子畫面,它只添加新的子畫面。這是因爲sprites配置項使用的是聲明式定義。如果要去維護子畫面,可以使用畫面的方法。

使用多個畫面

使用多個畫面主要是基於性能(或電池電量)這方面的考慮。因爲改變子畫面屬性會造成整個畫面(畫面中的其他所有子畫面)的重新渲染,通過畫面對不同 作用的子畫面進行分組,就可以只改變該畫面上分組的子畫面,而無須重新渲染整個畫面。建立在繪圖包上的Sencha圖表包,非常依賴該功能。譬如有一個需 要縮放交互的圖表,只需要根據圖表的拖動來重新渲染縮放的矩形,而不需要重新繪製系列和軸的畫面。

通過重寫上面的示例可以更好的理解這個概念:

var drawContainer = new Ext.draw.Container({
    renderTo: document.body,
    width: 250,
    height: 250});var mainSurface = drawContainer.getSurface(); // --- getSurface('main')mainSurface.add({ // add sprite to the surface
    type: 'rect',
    x: 50,
    y: 50,
    width: 100,
    height: 100,
    lineWidth: 4,
    strokeStyle: 'green',
    fillStyle: 'yellow'});

mainSurface.renderFrame(); // --- renders all the sprites in the surface

編輯子畫面屬性

現在,來修改子畫面的屬性,例如,將矩形子畫面變得更寬。

首先,需要獲取對子畫面的引用,其中的一種方式就是在畫面的items配置項中獲取,該配置項包含的是畫面中所有子畫面組成的數組。

var items = mainSurface.getItems(),
    rectSprite = items[0];

或者,使用畫面的get方法:

var rectSprite = mainSurface.get(0);

更好的方式是分配一個id給子畫面,並使用它來獲取子畫面:

mainSurface.add({
    type: 'rect',
    id: 'myRect',    ...});

var rectSprite = mainSurface.get('myRect');

現在,改變子緩慢的寬度,代碼如下:

rectSprite.setAttributes({    width: 150});// --- Don't forget to repaint the surface after changing sprite's attributesmainSurface.renderFrame();

可以看到,這裏使用了“rectSprite.setWidth(150);”來修改寬度,因爲width不是配置項。

演示

在這裏,還可以一次設置更多的屬性,這是一種推薦的和更有效率的方式。下面來修改填充顏色和畫筆顏色:

rectSprite.setAttributes({    fillStyle: 'rgba(255, 0, 0, .5)',
    strokeStyle: 'rgb(0, 0, 0)'});

在這裏,使用了CSS兼容的rgb功能來代替命名的顏色值來指定顏色值。

演示

嘗試一下去更改其他屬性,以便觀察它是如何影響子畫面的效果的。在Ext JS文檔中可以看到更多的所支持的其他屬性。

小結

正如所看到的,使用子畫面與使用組件沒有太大的不同,使用子畫面與使用組件所使用的原則是一樣的。使用與組件類似的語法代替直接處理HTML,可以節省直接處理SVG元素和Canvas API調用的時間。只需要創建子畫面並配置屬性,其餘的交給圖像包去處理。

在下一篇文章,將講述如何去實現子畫面的動畫功能、變換和交互,以及創建自定義的子畫面的方法和途徑。文章還將覆蓋子畫面諸如實例化和複用等功能,這將有助於提供性能和降低代碼的複雜性。

同時,希望大家能開心的去嘗試不同類型的子畫面,如在繪圖包中的圓型、線條或文本。

作者:Vitaly KravchenkoM/b>Vitaly is a Graphics Engineer at Sencha. Over the past two years, he has transitioned Touch Charts to a single cross-toolkit package, adding numerous features to the API, and improving interactivity and 3D charts support. For 10 years before joining Sencha, Vitaly was an independent developer. He built desktop audio software called Spider Player with a user base of 2 million people, as well as apps for BlackBerry, WebOS, and Android.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章