顯示具有 Adobe AIR 標籤的文章。 顯示所有文章
顯示具有 Adobe AIR 標籤的文章。 顯示所有文章

2013年9月17日 星期二

PullToRefresh

PullToRefresh 是作者製作的類別, 目的在Adobe AIR mobile 提供用戶下拉刷新動作, 建基於Feathers 的兩個元件(GroupedListList). 當用戶在目錄向下拉和放手, 會產生更新事件, 然後把目錄內容更新.

用戶把目錄向下拉 [範例]
   
用戶放手後, 目錄等待更新

以下是編寫的簡單步驟:

  1. 引入(Import) 相關的類別
    import feathers.controls.PullToRefreshList;
    import feathers.controls.List;
    
    
  2. 建立目錄內容
    var data:Array =
      [
        { text: "Aardvark" },
        { text: "Alligator" },
        { text: "Alpaca" },
        { text: "Anteater" },
      ];
    
    
  3. 建立目錄和添加事件監聽 (PULL_TO_REFRESH_EVENT)
    var list:List = new PullToRefreshList();
    list.dataProvider = new ListCollection(data);
    list.addEventListener(PullToRefreshList.PULL_TO_REFRESH_EVENT, listPullToRefreshHandler);
    this.addChild(list);
    
    
  4. 當用戶產生下拉刷新事件, 我們可以呼叫伺服器來更新目錄內容
    private function listPullToRefreshHandler(event:Event):void{
      ...
      // call server to return some data
      ...
    }
大家可以 [下載] 範例試試看.

2013年4月22日 星期一

原生手機對話框 (Native Dialogs)

NativeDialogs 是一個提供原生手機對話框的外掛. 它在iOS 和Android 系統提供接口給Adobe AIR 呼叫. 當中包括NativeAlert, NativeProgress, NativeListDialog, NativeDatePickerDialog, Text input Dialog 和Toast 等對話框.

NativeDatePickerDialog 的介面

日期對話框NativeDatePickerDialog 的呼叫語句:
var d:NativeDatePickerDialog = new NativeDatePickerDialog();
d.displayMode = NativeDatePickerDialog.DISPLAY_MODE_DATE;
d.title = "DatePicker";
d.message = "Select date:";
d.date = new Date();
d.show();

大家可以 [下載] 範例試試看, 作者在Flash Builder 設定NativeDialogs_AS.swcNativeDialogs.ane 外掛的路徑和關掉一些問題.

2013年4月17日 星期三

在iOS 背景運行Adobe AIR

作者發現在iOS 運行NetConnection 網路連結, 關閉螢幕後再啟動, 會產生錯誤導致程序崩潰. 這個錯誤不能以Try、Catch、Finally 捕捉錯誤事件. 我們必需在發佈的xml 檔案中, 加入以下設定來解決:

<iPhone>
    <InfoAdditions>
        <![CDATA[
            <key>UIApplicationExitsOnSuspend</key>
            <true/>
        ]]>
    </InfoAdditions>
</iPhone>

除了網路連結外, 在背景運行音樂和位置更新相關設定, 可以參考這個連結.

2013年1月28日 星期一

找不到iOS 裝置

作者在Windows 環境下, 使用Flash Builder 4.7 或Flash Professional CS6, 透過USB 連接iOS 裝置進行除錯發佈測試, 結果找不到任何iOS 裝置連接:

Flash Builder could not find a connected device.

以下是者作的電腦配置:
  • Windows 7 64 bit
  • iPad2 iOS 6.0
  • Flash Builder 4.7 或Flash Professional CS6 (Version 12.0.2.529) 更新請參考
  • Adobe AIR SDK 3.6
  • iTunes 11.0.1.12

在Goolge 找尋下, 發現一個方法可以暫時解決這個問題:
  1. C:\Program Files (x86)\Common Files\Apple\Apple Application Support\ 路徑, 找到SQLite3.dll
  2. SQLite3.dll 檔製至C:\Program Files\Adobe\Adobe Flash Builder 4.7 (64 Bit)\eclipse\plugins\com.adobe.flash.compiler_4.7.0.XXXXXX\AIRSDK\lib\aot\bin\iOSBin\

其實這個問題, 不是每個電腦會發生, 者作朋友的電腦在相同配置條件下, 亦不會遇上. 相信與電腦內曾安裝SQLite 軟件有關係.


後記:
對Flash Professional CS6 的用戶, 解決方法與Flash Builder 相似, 設定Adobe AIR SDK 請參考.

2013年1月17日 星期四

P2P 指令同步播放影片

作者製作一個處理Peer-to-peer(P2P) 的物件(P2PCore), 它透過Action Script 原生的NetConnectionNetGroup, 簡單地傳送文字, 圖像或物件, 達成點對點資料傳送.


以下為大家介紹, 如何利用P2P 技術, 在iPad 與PC 之間同步播放影片: 
  1. 建立P2PCore 物件, 為它加入監聽事件:
    var _core:P2PCore = new P2PCore();
    _core.addEventListener(P2PEvent.LOAD,loadHandler);
    _core.addEventListener(P2PEvent.MESSAGE, messageHandler);
    

  2. 當P2PCore 連接成功, 為用戶介面加入監聽事件:
    function loadHandler(event:P2PEvent):void{
      scaleX1Btn.addEventListener(MouseEvent.CLICK, scaleX1ClickHandler);
      scaleX2Btn.addEventListener(MouseEvent.CLICK, scaleX2ClickHandler);
      video.addEventListener("stateChange", playheadUpdateHandler);
    }
    

  3. 當按下Scale x1 或Scale x2 按鈕, 透過P2PCore 廣播給所有裝置改變影片大小:
    function scaleX1ClickHandler(event:MouseEvent):void{
      video.setScale(1, 1);
      _core.sendObject({type:"setScale", value:1});
    }
    function scaleX2ClickHandler(event:MouseEvent):void{
      video.setScale(2, 2);
      _core.sendObject({type:"setScale", value:2});
    }
    

  4. 當改變影片播放位置, 透過P2PCore 廣播給所有裝置最新播放位置:
    function playheadUpdateHandler(event:Event):void{
      _core.sendObject({type:"playheadTime", value:video.playheadTime.toString()});
      video.play();
    }
    

  5. 若裝置接收廣播訊息, 改變影片大小或播放位置:
    function messageHandler(event:P2PEvent):void{
      var msg:P2PMessage = event.value as P2PMessage;
      switch(msg.data.type){
        case "setScale":
          video.setScale(msg.data.value, msg.data.value);
        break;
        case "playheadTime":
          // <----- only allow one controller
          video.removeEventListener("stateChange", playheadUpdateHandler);
          
          video.playheadTime = parseFloat(msg.data.value);
          video.play();
        break;
      }
    }
這個實例主要運用發出和接收指令, 達到影片同步播放功能, WiFi 穩定性會直接影響iPad 與PC 之間的同步效果. 若希望製作串流影片, 請參考這個連結.

大家可以 [下載] 範例試試看.

注意事項:
 - 在Flash Professional CS6 透過USB 連接iOS 安裝發佈請參考這個連結.
 - Flash Media Server 我們可以申請Adobe 公開伺服器 (rtmfp://stratus.adobe.com/) 作試驗或自行架設.

2013年1月10日 星期四

Flash Professional CS6 透過USB 連接iOS 安裝發佈

在Flash Professional CS6 版本12.0.2.529 中, 我們可以透過USB 連接iOS 裝置, 進行實機測試. 在Windows 或MAC OS X 平台兩者皆可, 過程無需透過iTunes 或越獄(Jailbreak) 後的iOS 裝置, 純粹USB 連接, 十分方便.

以下是更新Flash Professional CS6 和連接iOS 發佈方法:
  1. 在官方下載最新Flash Professional CS6 更新:

  2. 安裝完成後, 在Help -> Aboout Adobe Flash Professional 看到新版本編號 (12.0.2.529).

  3. 下載Adobe AIR SDK, 然後設定路徑. (設定方法請參考)

  4. 開啟一個AIR for iOS  新專案.

  5. 設定發佈對象為AIR 3.4 for iOS 或以上版本.

  6. AIR for iOS Settings -> Deployment 中, 選擇以USB 連接iOS 裝置進行實機測試.
    (Install application on the connected iOS device)


注意事項:
若曾經修改host 檔案, 在更新過程會發生錯誤訊息, 請把host 檔案暫時回復, 待更新完成後才可修改.
(host 檔案路徑: C:\Windows\System32\drivers\etc\host)

2012年10月17日 星期三

Adobe AIR 與Push Notifications

為大家介紹Adobe AIR 原生支援的Push Notifications 功能, 配合apns-php 伺服器發出訊息給iOS 裝置.

簡單測試需要的準備:
  • Adobe AIR 3.4 或以上SDK (安裝SDK 於Flash Builder 請參考)
  • 一個iOS 裝置 (不能以XCode Simulator 來取代)
  • 需要.p12, .mobileprovision 與.pem 檔 (製作包含Push Notifications 功能請參考)
  • 一個執行Push Notification Provider 的伺服器, 我們可以使用apns-php


Push Notifications 的運作原理:

  • 使用Adobe AIR 提供的介面(RemoteNotifier) 並執行訂閱(subscribe), 取得一個Device Token (這是每個iOS 裝置獨一無異的記號)
  • 把Device Token 提交給伺服器記下
  • 利用Push Notification Provider 發放訊息給這些Device Token
  • 這個iOS 裝置會收到Push Notification
Push Notifications 基本工作流程


Adobe AIR 提供以下三種Push Notification 提示:
  • NotificationStyle.ALERT - 在收到通知時顯示警告方塊的通知
  • NotificationStyle.BADGE - 收到通知時會以數字/影像更新應用程式圖示的通知
  • NotificationStyle.SOUND - 在收到通知時播放聲音的通知
Adobe AIR 在iOS 接收Push Notifications

在Adobe AIR 程式編寫, 提供一個按鈕給用戶按下(clickHandler), 取得iOS 裝置的Device Token:
private function clickHandler(event:MouseEvent):void{
  trace("clickHandler: " + RemoteNotifier.supportedNotificationStyles.length);
  myTxt.appendText("clickHandler: " + RemoteNotifier.supportedNotificationStyles.length+"\n");
  
  if ( RemoteNotifier.supportedNotificationStyles.length > 0)
  {
    var preferredNotificationStyles:Vector.<string> = new Vector.<string>;
    
    preferredNotificationStyles.push(NotificationStyle.ALERT);
    preferredNotificationStyles.push(NotificationStyle.SOUND);
    preferredNotificationStyles.push(NotificationStyle.BADGE);
    
    var subscribeOptions:RemoteNotifierSubscribeOptions = new RemoteNotifierSubscribeOptions();
    subscribeOptions.notificationStyles = preferredNotificationStyles;
    
    rn = new RemoteNotifier();
    
    rn.addEventListener(RemoteNotificationEvent.TOKEN, sendDeviceTokenToServer);
    rn.addEventListener(StatusEvent.STATUS, subscriptionFailureCallback);
    
    rn.subscribe(subscribeOptions);
  }
}
protected function subscriptionFailureCallback(event:StatusEvent):void
{
  trace("Received Status event for registrationFailure with code:" + event.code + " and level:" + event.level + "\n");
  myTxt.appendText("Received Status event for registrationFailure with code:" + event.code + " and level:" + event.level + "\n");
}
protected function sendDeviceTokenToServer(event:RemoteNotificationEvent):void
{
  trace("Received " + event.type + " with tokenString:" + event.tokenId + "\n");
  myTxt.appendText("Received " + event.type + " with tokenString:" + event.tokenId + "\n");
}

在Adobe AIR 程式發佈設定:
  • Certificate 和Provisioning file 需要使用包含Push Notifications 功能的.p12 和 .mobileprovision 檔
  • 在XML 設定檔加入Entitlements 設定:
    <iPhone>
      <Entitlements><![CDATA[
        <key>get-task-allow</key>
        <true/>
        <key>aps-environment</key>
        <string>development</string>
        <key>keychain-access-groups</key>
        <array>
          <string>KEYCHAIN_ACCESS_GROUP</string>
        </array>
      ]]></Entitlements>
    </iPhone>
  • 在Flex Compiler > Additional compilder arguments: 更改成:
    -locale en_US -swf-version=17

架設apns-php 伺服器後, 我們更改sample_push.php 的內容作為發訊測試:
  • 更改.pem 檔名稱, 並把.pem 檔案複製至與sample_push.php 同一資料夾內
  • 加入iOS 裝置的Device Token
更改sample_push.php 內容

當執行sample_push.php 後, 測試對像的iOS 裝置會接收到Push Notification. 大家可以 [下載] 範例試試看.

參考資料: http://blogs.adobe.com/airodynamics/2012/05/29/push-notifications-support-in-ios/

2012年10月16日 星期二

製作p12, mobileprovision 與pem

製作p12 :  認證檔 iOS Certificate (包含Push Notifications 功能)
  1. 進入iOS Provisioning Portal, 在App IDsNew App ID

  2. 輸入新增程式的名稱 (NameApp ID)

  3. 找尋新增的程式, 按下Configure

  4. 啟動Enable for Apple Push Notification service, 並在Development Push SSL Certificate 按下Configure

  5. 然後按指示, 在MAC OS X 的Utilities 開啟Keychain Access, 選擇:
    Keychain > Certificate > Assistant > Request a Certificate from a Certificate Authority

  6. 產生一個csr 檔, 並儲存於桌面上

  7. 把桌面上的csr 檔上載給iOS Provisioning Portal 處理

  8. 處理完成後, 會產生一個cer 檔, 把它下載至桌面

  9. 在桌面執行cer 檔後, 在Keychain Access 會新增一個Certificate

  10. 在新增的Certificate 右按Export 產生p12 檔


製作mobileprovision :  描述檔 Provisioning Profile
  1. ProvisioningDistribution 選擇New Profile

  2. 輸入Profile Name 等資料

  3. 手動更新iOS Provisioning Portal 網頁(數秒時間便可), 直至新增的項目提供mobileprovision 檔下載按鈕


製作pem :  數位憑證 Push Certificate
  1. 開啟MAC OS X 的Terminal, 移至儲存p12 檔的桌面位置: (請更改為正確路徑)
    cd /Users/YOUR_USER_NAME/Desktop/
  2. 然後輸入以下指令產生pem 檔:
    openssl pkcs12 -in Certificates.p12 -out server_certificates_bundle_sandbox.pem -nodes -clcerts

若大家沒有開發者帳號, 可考慮暫時使用假認證檔(p12) 和描述檔(mobileprovision) 作測試. 待日後正式發佈時, 才購買開發者帳號.

2012年10月10日 星期三

as3dpad 操控桿介紹

as3dpad 是作者製作的一個類別庫, 目的在Adobe AIR mobile 提供一個虛擬操控桿, 於iOS 和Android 等流動裝置運作, 為遊戲提供一個輸入方法.

配合Starling 的 [範例] (請以鍵盤WASDm, 操控)

as3dpad 渲染部分參考SpriteSheetClip 的手法, 所以在stage3d 之上有效運作, 與Starling 等框架相容.
另外, 類別庫提供以鍵盤代替螢幕輸入(WASDm,), 給開發人員在電腦直接測試遊戲.

弧度(radians) 表示操控桿位置

以下是編寫的簡單步驟:
  1. 建立DPad 物件
    var dPad:DPad = new DPad();
    this.addChild(dPad);
    
  2. 接收X 軸與Y 軸回傳的數據
    dPad.leftPad.addEventListener(DPadEvent.TOUCH_PRESS, touchPressHandler);
    dPad.leftPad.addEventListener(DPadEvent.TOUCH_RELEASE, touchReleaseHandler);
    
    private function touchPressHandler(event:DPadEvent):void{
      var axisPad:AxisPad = event.target as AxisPad;
      trace("radians: " + axisPad.radians);
      trace("distance: " + axisPad.distance + "/" + axisPad.maxDistance);
      trace("press left:  " + (axisPad.value & AxisPad.LEFT));
      trace("press right: " + (axisPad.value & AxisPad.RIGHT));
      trace("press up:    " + (axisPad.value & AxisPad.UP));
      trace("press down:  " + (axisPad.value & AxisPad.DOWN));
    }
    private function touchReleaseHandler(event:DPadEvent):void{
      ...
    }
    
  3. 接收A 和B 按鈕回傳的數據
    dPad.rightPad.addEventListener(DPadEvent.TOUCH_PRESS_A, touchPressAHandler);
    dPad.rightPad.addEventListener(DPadEvent.TOUCH_PRESS_B, touchPressBHandler);
    dPad.rightPad.addEventListener(DPadEvent.TOUCH_RELEASE_A, touchReleaseAHandler);
    dPad.rightPad.addEventListener(DPadEvent.TOUCH_RELEASE_B, touchReleaseBHandler);
    
    private function touchPressAHandler(event:DPadEvent):void{
      var groupPad:GroupPad = event.target as GroupPad;
      trace("press A: " + (groupPad.value & GroupPad.A_BUTTON));
      trace("press B: " + (groupPad.value & GroupPad.B_BUTTON));
    }
    private function touchPressBHandler(event:DPadEvent):void{
        ...
    }
    private function touchReleaseAHandler(event:DPadEvent):void{
        ...
    }
    private function touchReleaseBHandler(event:DPadEvent):void{
        ...
    }

類別庫提供以下範例參考:
  • example01_basic - 基本用法 [demo]
  • example02_custom_UI - 自定介面 [demo]
  • example03_double_AxisPad - 雙操控桿 [demo]
  • example04_touch9Grid - 螢幕九格觸控 [demo]
  • example05_starling - 配合Starling [demo]

Launch Examples Launch Examples Launch Examples Launch Examples Launch Examples

大家可以 [下載] 範例試試看.

2012年9月26日 星期三

[教學] Panorama 全景圖實作

日本的Spark project 為Action Script 開發人員提供大量程式庫. 其中AlternativaTemplate 編寫的Camera 操作控制, 能簡單實作全景圖, 並透過Alternativa3D 運行Stage3D 硬體加速顯示.

請按 [觀看] 範例

以下是編寫的步驟:

  1. 建立一個新類別並繼承AlternativaTemplate 類別
  2. 設定CameraCameraType.PANORAMA 模式
  3. 設定紋理材料(TextureMaterial) 為內嵌的全景圖像(assets/test1.jpg)
  4. 建立一個幾何球體(GeoSphere) 並貼上紋理材料
package
{
  import alternativa.engine3d.materials.TextureMaterial;
  import alternativa.engine3d.primitives.GeoSphere;
  import alternativa.engine3d.resources.BitmapTextureResource;
  
  import org.libspark.alternativa3d.camera.CameraType;
  import org.libspark.alternativa3d.view.AlternativaTemplate;
  
  [SWF(backgroundColor="#000000", frameRate="60", quality="LOW", width="800", height="480")]
  public class Alternativa_Panorama extends AlternativaTemplate
  {
    [Embed(source = "assets/test1.jpg")]
    private static var ImageCls:Class;
    
    public function Alternativa_Panorama():void{
      super({
        cameraType:CameraType.PANORAMA,
        useDiagram : true
      });
    }
    override protected function atInit():void{
      var material:TextureMaterial = new TextureMaterial(new BitmapTextureResource(new ImageCls().bitmapData));
      var shpere:GeoSphere = new GeoSphere(100, 32, true, material);
      scene.addChild(shpere);
    }
  }
} 
在Android 和iOS 運作正常, 大家可以 [下載] 範例試試看.

參考資料: http://clockmaker.jp/blog-en/2011/11/alternativa3d-panorama/

2012年9月7日 星期五

AIRKinect 怪獸

AIRKinect 配合Away3D 可以製作很多有趣事, 我們把Away3D 當中的怪獸, 配合AIRKinect 的骨架移動3D 模型, 怪獸起動來喔~~~



只要修改AIRKinect 內建範例, 把關節名稱對應為Away3D 怪獸範例的模型:
var jointMapping:Vector.<Number> = Vector.<Number>([
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("head"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("neck"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("waist"),
  
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("luparm"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("lloarm"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("lhand"),
  
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("ruparm"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("rloarm"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("rhand"),
  
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("lupleg"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("lloleg"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("lfoot"),
  
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("rupleg"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("rloleg"),
  (mesh.animationState.animation as SkeletonAnimation).skeleton.jointIndexFromName("rfoot")
]);

大家可以 [下載] 範例試試看.

2012年9月2日 星期日

foxhole 元件

foxhole 是一個以Starling Framework 為基礎的元件庫, 與MadComponents 性質十分相似, 它們都是以Stage3D 技術, 在iOS 或Android 中流暢操作的UI 框架.

請按 [觀看] Layout Explorer 範例

請按 [觀看] Gallery 範例

請按 [觀看] Tile List 範例

foxhole 主要透過程式編寫來決定元件的位置與關係. 與MadComponents 的XML 設定有所不同.

API 參考: http://flashtoolbox.com/foxhole-starling/documentation/

2012年8月29日 星期三

Flash Builder 4.7 beta

Adobe Lab, 我們可以免費下載最新Flash Builder 4.7 beta 版. 這版本支援Adobe AIR 3.4 以下兩個功能:
  • 以USB 連接iOS 裝置部署(deployment) 和除錯(debugging)
  • 或發佈於Xcode 中的iOS simulator 運作 (只限MAC OS X)



由於Flash Builder 4.7 beta 版不是內置Adobe AIR 3.4, 我們需要作以下設定:
  1. 下載Flash Builder 4.7 beta 版和完成安裝
  2. 下載Adobe AIR 3.4 SDK
  3. 對MAC OS X 使用者, 請參考這個SDK 設定. (若Windows 使用者請參考這個)
  4. 最後, 我們在Run -> Run Configurations -> Mobile Application 找到新的設定介面, 在<Choose launch method> 可以選擇三個方式發佈:
     - On AIR Simulator
     - On iOS Simulator
     - On device

Flash Builder 4.7 在發佈上的優化, 對開發者帶來方便, 實在是一件好事.
關於認證檔(Certificate) 和描述檔(Provisioning file) 設定大家可以參考這個.

2012年8月27日 星期一

MadComponents 元件

在Stage3D 技術發展下, 我們會找到很多相關應用, 在UI 元件也分享到硬體加速的成果. MadComponents 是其中一個在免費的框架, 目的是在iOS 或Android 以同一個UI 操作介面, 透過Stage3D 技術流暢運作.

請按 [觀看] 範例一
請按 [觀看] 範例二

開發人員主要透過XML 作介面設定, 我們來個簡單的Hello World 示範: [下載]

package
{
  import com.danielfreeman.madcomponents.UI;
  
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  
  [SWF(backgroundColor="#ffffff", frameRate="60", quality="LOW")]
  public class madcomponents_test01 extends Sprite
  {
    protected static const HOME_VIEW:XML = <vertical>
                        <label>Hello, World!</label>
                        <button>Continue</button>
                         </vertical>;  
    
    public function madcomponents_test01()
    {
      super();
      
      stage.align = StageAlign.TOP_LEFT;
      stage.scaleMode = StageScaleMode.NO_SCALE;
      
      UI.create(this, HOME_VIEW);
    }
  }
}

MadComponents 還有很多實用元件, 在官方的文件教程(Tutorial) 中有詳細說明:


以下是官方提供己利用MadComponents 框架製作, 並發佈於App Store 和Google Play 中的程式:
대전맞고 온라인 고스톱
The Etiquette App
Actionary
SimsUShare Mobile Lite

在Adobe AIR 發展領域, 跨平台的高效能元件, 相信會是其中的一個優勢.
除了Appcelerator Titanium 以javascript 作編寫語言, 然後編譯成源生元件. 我們還可以選擇MadComponents.

API 參考: http://e2easy.byethost9.com/madcomponents/