【Flex3】 package ベースで画像をロードするブログパーツを作成する

自分で書いた絵をフェードアウト・フェードインしながら表示するブログパーツですが、
前回の決め打ちから XML を使って画像リストやオプションを指定できるように進化しています。

ネットワーク障害でリクエストに失敗しても、5秒間隔でリトライします。
xml に関しては、キャッシュが効かないようにしていますので、xml の内容を変更しても
ブラウザをリロードすればすぐに反映されます。

画像は元々キャッシュされるので、ネットワーク障害とかは関係無いはずです。

※ type で random と seq が選べます( どちらでもなければ seq です )
<?xml version="1.0" encoding="utf-8"?>
<data>
    <options>
        <type>random</type>
        <delay>5000</delay>
        <first>http://lightbox.matrix.jp/timg/1217433566200507.png_S.jpg</first>
        <no>4</no>
        <comment>utf-8で保存できるように日本語で書いています</comment>
    </options>
    <images>
        <no>1</no>
        <url>http://lightbox.matrix.jp/timg/1225300426141908.png_S.jpg</url>
    </images>
    <images>
        <no>2</no>
        <url>http://homepage2.nifty.com/lightbox/timg/1229709460227982.png_S.jpg</url>
    </images>
    <images>
        <no>3</no>
        <url>http://lightbox.if.land.to/timg/1224216851694379.png_S.jpg</url>
    </images>
    <images>
        <no>4</no>
        <url>http://lightbox.matrix.jp/timg/1217433566200507.png_S.jpg</url>
    </images>
</data>





ブラウザでダウンロード


↓これです(IFRAME で埋め込んでいます)
<IFRAME
	src="http://winofsql.jp/flex3/as_tool/Main.htm"
	frameborder="no"
	scrolling="no"
	width="160"
	height="240"
></IFRAME>

ソースコード
画像の URL を XML で読み込んでいるので、イベントの橋渡しが一つ増えました。
最初に XML が読み込め無いと後へ続けれないので、失敗した場合はタイマーで
繰り返しリトライしています。

成功した場合は、そこから初回ロードになってイベントのループが開始されます。

データが XML に入っているので、ロード処理は簡単になっています。
とにかく重要なのは、イベントの考え方で、それぞれが発射台みたいな感じで
ドミノ式に処理が進行します

デバッグ表示は、ブラウザの表示部分のフラッシュ以外の部分をクリックして、F12 です。
( Firebug )
// *********************************************************
// Flex3( mx 無し )
//
// ◎ 画像表示パーツ
// xml取得 => 初回load
//         => 取得失敗の場合は 5 秒間隔でリトライ
// load => onload => time(5秒) => fadeout(0.5秒) => load
//         fadein は、1秒なので先に終わる
//         5秒後に fadeout が始まり
//         fadeout ではいったんタイマー停止して
//         fadeout が終わると loadImages へ 
// *********************************************************
package {

import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.net.*;
import flash.external.*;
import mx.effects.*;
import mx.events.*;
import mx.rpc.http.*;
import mx.rpc.events.*;

// 背景色
[SWF(width="160",height="220",backgroundColor="#FFFFFF")]

// 表示用クラス 【Sprite】を継承
public class Main extends Sprite {

	[Bindable]
	[Embed("mail.png")]
	private var imgMail:Class;

	private var myTimer:Timer = new Timer(5000);
	private	var loader:Loader = new Loader();
	private var counter:int = 0;

	private var fadeIn:Fade;
	private var fadeOut:Fade;

	private var srv:HTTPService = new HTTPService();
	private var init_flg:Boolean = true;
	private var image_no:int = 0;
	private var xdata:XML;
	private var image_cnt:int = 0;

	// *********************************************************
	// コンストラクタ
	// *********************************************************
	public function Main():void {

		ExternalInterface.call("console.log", "start");

		// stage の設定
		stage.scaleMode = StageScaleMode.NO_SCALE;
		stage.align = StageAlign.TOP_LEFT;

		// 埋め込み画像を表示
		var myImg:Bitmap = new imgMail();
		myImg.x = 0;
		myImg.y = 162;
		stage.addChild(myImg);


		// フェードイン用
		fadeIn = new Fade(loader);
		fadeIn.duration = 1000;
		fadeIn.alphaFrom = 0;
		fadeIn.alphaTo = 1;

		// フェードアウト用( フェードアウト終了後、load イベント )
		fadeOut = new Fade(loader);
		fadeOut.duration = 500;
		fadeOut.alphaFrom = 1;
		fadeOut.alphaTo = 0;
		fadeOut.addEventListener(EffectEvent.EFFECT_END, loadImages);

		// 読み込みタイマーを登録
		myTimer.addEventListener("timer", fadeOutProc );


		// とにかく表示データが必要なので、最初にリクエスト
		srv.addEventListener( ResultEvent.RESULT, resultHandler);
		srv.addEventListener( FaultEvent.FAULT, faultHandler);

		// キャッシュさせない為に Math.random() の値を追加しています
		srv.url = "images.xml?id=" + Math.random();
	
		// レスポンス結果のデータフォーマット
		srv.resultFormat = "e4x";
		srv.method = "GET";
		srv.send();
	}

	// *****************************************************
	// HTTPServiceが成功
	// *****************************************************
	private function resultHandler(e:ResultEvent):void {

		xdata = XML(e.result);

		ExternalInterface.call("console.log", xdata.options.delay );
		myTimer.delay = xdata.options.delay;

		ExternalInterface.call("console.log", xdata.images.length() );
		image_cnt = xdata.images.length();


		// 最初のロード
		loader.x = 20;
		loader.y = 0;
		loader.alpha = 0;
		stage.addChild(loader);
		// 読み込み完了イベントを登録
		loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
		loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loadError);
		loader.load(
			new URLRequest( xdata.options.first )
		);
		// 初回画像番号( 画像リストに無い場合は 0 とすれば良い )
		image_no = xdata.options.no;

		// データ取り込み完了
		init_flg = false;

	}

	// *****************************************************
	// HTTPServiceでエラーが発生した
	// *****************************************************
	private function faultHandler(e:FaultEvent):void {

		ExternalInterface.call("console.log", e.fault.message);

		// データ取得に失敗( ネットワークエラーか xml が無い )
		// ので5秒後に再度リトライ
		myTimer.start();

	}

	// *********************************************************
	// 画像をロードして表示
	// *********************************************************
	private function fadeOutProc(event:TimerEvent):void {

		ExternalInterface.call("console.log", "fadeOutProc");

		// タイマー停止
		myTimer.stop();
		if ( init_flg ) {
			// データ取得に失敗しているのでリトライ
			srv.send();
		}
		else {
			// この処理が完了すると、↓の function が開始される
			fadeOut.play();
		}

	}

	// *********************************************************
	// 画像をロードして表示
	// *********************************************************
	private function loadImages(event:EffectEvent):void {

		ExternalInterface.call("console.log", "loadImages");

		// ランダム表示
		if ( xdata.options.type == "random" ) {
			// 前回と連続しない画像番号
			while( 1 ) {
				counter = 1 + Math.floor(Math.random() * (image_cnt - 1 + 1))
				if ( counter != image_no ) {
					image_no = counter;
					break;
				}
			}
		}
		// 順次表示
		if ( xdata.options.type == "seq" ) {
			counter++;
			if ( counter > image_cnt ) {
				counter = 1;
			}
		}
		if ( xdata.options.type != "seq" && xdata.options.type != "random" ) {
			counter++;
			if ( counter > image_cnt ) {
				counter = 1;
			}
		}

		ExternalInterface.call("console.log", counter );

		ExternalInterface.call("console.log", "load");
		// XML データよりロード
		loader.load(
			new URLRequest(
				xdata.images[counter-1].url
			)
		);

	}

	// *********************************************************
	// 読み込み完了イベント
	// *********************************************************
	private function loadComplete(e:Event):void {

		ExternalInterface.call("console.log", "loadComplete");
		fadeIn.play();

		// 5秒後に フェードアウト開始
		myTimer.start();
	}

	// *********************************************************
	// 読み込みエラーイベント
	// *********************************************************
	private function loadError(e:IOErrorEvent):void {

		ExternalInterface.call("console.log", "load error");
		myTimer.start();
	}

}}