WordPressテーマ変更

今まで使っていたテーマは、ページ内容丸ごと表示していたので、目次のような形で見れなかったんだけど。

トップページとか、Archives一覧とかを表示したときに、ページの要約を一覧表示したいとおもって、テーマ変更することにした。(でも、デザインはちょっと味気ないかなぁ)

Advertisements

Flash ActionScript3で画像を表示する

ホームページのトップページに、ちょっとした動きを付けたタイトルを用意したいということで、Flashを使ってみることにしました。
が、Adobeのソフトは値段が高いので、Flex SDKを使って黙々とコーディングしています。

画像を表示するやり方としては、「Embedで画像ファイルを埋め込む」、「Loaderで画像ファイルを読込む」の2通りあるみたい。
簡単に比べてみると

(A)Embedを使った場合、
コンパイル時にソースコードといっしょに画像もswfファイルに埋め込まれる。
画像が埋め込まれる分、swfファイルサイズが大きくなる。
swfファイル1つに全部入るので、HTMLからの呼び出しは簡単そう?。
画像を修正・変更したら、ソースコードと一緒に再コンパイルが必要

(B)Loaderを使った場合、
swfファイルの外にある画像ファイルを読込む。
画像がswfファイルに埋め込まれないため、その分ファイルサイズは大きくならない。
swf外部に画像ファイルを配置しておく必要がある。他サイトの画像を読込むこともできる。
画像ファイルの読込が完了したかを判定してから、後続の処理に移るようにする必要がある。

っていう感じみたい。

あと、画像の動かし方については、「Timerクラスを使って時間をカウントしておいて、その時間に合わせて画像の位置を修正する」、っていうやり方があるみたいなんだけど、複数の画像を別々に動かしたりするのが大変そう。
なので、アニメーション用のライブラリtweenerを使うことにした。

そんなわけで、「Flashで画像を表示するやり方2つ」と、「ライブラリtweenerを使って動かしてみる」、っていうのを試してみたので以下にメモ。

※FlexSDK4.6.0を使っています



1.Embedで画像ファイルを埋め込んでみた

ActionScriptのメタデータタグで画像読み込みさせます。このとき、画像ファイルはソースコードと同じところにimgディレクトリを作って、その中においています。

[Embed(source=’img/met001_s.jpg’, mimeType=”image/jpeg”)]
private static const TestImage01:Class;

そのあと、addChildすると、とりあえず画像表示できる。

var imgObj01:Bitmap = new TestImage01();
addChild(imgObj01);

これを踏まえて、「複数画像を、サイズと位置を指定してから表示してみた」ソースコードは以下の通り

package  {
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.events.MouseEvent;

    public class EmbedImage extends Sprite{

        [Embed(source='img/met001_s.jpg', mimeType="image/jpeg")]
        private static const TestImage01:Class;

        [Embed(source='img/met002_s.jpg', mimeType="image/jpeg")]
        private static const TestImage02:Class;

        public function EmbedImage(){
            var imgObj01:Bitmap = new TestImage01();
            // 画像のサイズを設定
            imgObj01.width = 100;
            imgObj01.height = 100;
            // 画像の位置を設定
            imgObj01.x = 0;
            imgObj01.y = 0;

            addChild(imgObj01);

            var imgObj02:Bitmap = new TestImage02();
            // 画像のサイズを設定
            imgObj02.width = 100;
            imgObj02.height = 100;
            // 画像の位置を設定
            imgObj02.x = 100;
            imgObj02.y = 100;

            addChild(imgObj02);

        }
    }
}

とりあえずこんな感じで、表示できました。


2.Loaderで画像ファイルを読込んでみた

処理の流れをまず確認すると、

(a)loaderで画像を読込む
(b)画像の読み込み完了したかどうかを検知。
(c)addChildで画像を表示

って感じになる。

(b)の検知にはaddEventListenerメソッドを使い、Listenerをあらかじめ仕込んでおきます。なので、ソースコード上は、(a)の前にListenerを仕込むことになります。

ソースコードのイメージはこんな感じになる。

まず、Loaderを作成して、Listenerを設定する。Listenerのところでは、Event.INITを検知したら、initというメソッドが呼ばれるように設定しておく。そのあと、IMAGE_URLで画像ファイルのパスを指定して、画像を読込むことになります。

flickr等のサイトから画像を取得する場合は、
「 Security.loadPolicyFile(“http://farm3.static.flickr.com/crossdomain.xml”);  」といった形でcrossdomain.xmlを読込ませる必要があるみたいです。僕の場合、自分のサイト上の画像ファイルを読込ませるため、省略しています。

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, init);
loader.load(new URLRequest(IMAGE_URL), new LoaderContext(true));

読み込み完了したら、initが呼び出され、その中で画像表示。

private function init(event:Event):void
{
addChild(images);
}

ただしこれだと、複数の画像を読み込むときに問題があります。ファイルが1つ読み込み完了すると、そのイベントが検知されてinitが呼ばれてしまい、そのときにほかの画像がまだ読み込まれていない可能性があります。とくに外部のファイルをインターネット経由でとりにいっているような場合は、ファイルの読込時間の差が大きくなると思われます。

そこで処理の流れを修正し、「initの中で画像追加するのではなく、initの中ですべての画像が読み込み完了したかを判定する」ように変更します。すべて読み込み完了していたら、次の処理をよびだし、そこで画像の表示を行うような形にします。

まず、画像ファイルのパスを、IMAGE_URL:Arrayで配列変数に設定しておきます。
private    const IMAGE_URL:Array =
[
img_dir + “/met001_s.jpg”,
img_dir + “/met002_s.jpg”
];

画像の読込は、for文でまとめて読込ませます。それぞれの画像ファイル読み込みでListenerが設定されます。

for (var i:int = 0; i < IMAGE_URL.length; i++)
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, init);
loader.load(new URLRequest(IMAGE_URL[i]), new LoaderContext(true));
loader.name = i.toString();
}

画像読み込みが1つ完了するごとにinitが呼ばれます。initの中では、呼ばれた回数をカウントしておき、すべての画像ファイルが読み込まれたかどうかを判定します。
すべて読み込み完了したら、次の処理(ここではcompleteHandlerと命名しています)を呼び出すようにしておきます。

private function init(event:Event):void
{
images[event.currentTarget.loader.name] = event.currentTarget.loader;
if (++count == IMAGE_URL.length) completeHandler();
}

completeHandlerの中で、画像ファイルを表示していきます。

private function completeHandler():void
{
for (var i:int = 0; i < images.length; i++)
{
addChild(images[i]);
}
}

これを踏まえて、「複数画像を、サイズと位置を指定してから表示してみた」ソースコードは以下の通り

package  {
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;

    import flash.system.LoaderContext;
    import flash.system.Security;

    [SWF(width = "500", height = "300", backgroundColor = "0xF9F9F9", frameRate = "24")]

    public class LoadImage1 extends Sprite {

        private var count:int = 0;    // 読み込んだ画像数
        private var images:Array;    // 読み込んだ画像

        private var flashvars:Object = loaderInfo.parameters;
        //private var img_dir:String = flashvars["img_dir"];
        private var img_dir:String = "./img";  // 単体テスト用

        private    const IMAGE_URL:Array =
        [
            img_dir + "/met001_s.jpg",
            img_dir + "/met002_s.jpg"
        ];

        public function LoadImage1() {

            images = new Array(IMAGE_URL.length);

            for (var i:int = 0; i < IMAGE_URL.length; i++)
            {
                var loader:Loader = new Loader();
                loader.contentLoaderInfo.addEventListener(Event.INIT, init);
                loader.load(new URLRequest(IMAGE_URL[i]), new LoaderContext(true));
                loader.name = i.toString();
            }
        }

        private function init(event:Event):void
        {
            images[event.currentTarget.loader.name] = event.currentTarget.loader;
            if (++count == IMAGE_URL.length) completeHandler();
        }

        private function completeHandler():void
        {

            images[0].x = 0;
            images[0].y = 0;
            images[1].x = 60;
            images[1].y = 0;

            for (var i:int = 0; i < images.length; i++)
            {
                images[i].width = 60;
                images[i].height = 60;

                addChild(images[i]);

            }

        }
    }
}

とりあえずこんな感じで、表示できました。

参考サイト
ActionScript入門Wiki – 複数の画像を読み込む(基本編)
ActionScript3で外部画像の読み込みと表示&サイズ指定[AS3] | QUALL – blog


3.tweenerで画像ファイルを動かしてみた

addChildで画像を表示した後に、Tweenerクラスを用いて画像を動かすことができます。

最終的にどこに動かすかを指定すると、そこまで動かしてくれます。書き方はこんな感じ。

Tweener.addTween(images[0], {
time: 5,    // 5秒間のアニメーション
delay: 2.3,
scaleX: 0.2,  // s の scaleX を 遷移
scaleY: 0.2,  // s の scaleY を 遷移
x: 0,
y: 100
//transition: “easeInBounce”,
});

各パラメータはこうなってます。

timeで、どのくらい時間(秒)をかけて動かすか
delayで開始時間をどのくらい遅らせるか(秒)
scaleX、scaleYは、何倍に拡大するか。(今回使った画像のサイズが1024pixelと大きいため、拡大率を小さくしています)
x、yは移動先の座標
transitionは、動かし方の指定です。「一定の速度で動かす」とか、「初め早くて後はゆっくり」、といったことができます。くわしくはこちら。Transition Types

実際に動かすとこんな感じになりました。(BlogへのFlashの埋め込みがうまくいかないので、画像キャプチャしました・・・)

ソースコードは以下のような形になります。

package  {
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;

    import flash.system.LoaderContext;
    import flash.system.Security;

    import caurina.transitions.Tweener;
    import caurina.transitions.properties.FilterShortcuts;

    [SWF(width = "500", height = "300", backgroundColor = "0xF9F9F9", frameRate = "24")]

    public class LoadImage2 extends Sprite {

        private var count:int = 0;    // 読み込んだ画像数
        private var images:Array;    // 読み込んだ画像

        private var flashvars:Object = loaderInfo.parameters;
        //private var img_dir:String = flashvars["img_dir"];
        private var img_dir:String = "./img";  // 単体テスト用

        private    const IMAGE_URL:Array =
        [
            img_dir + "/met001_s.jpg",
            img_dir + "/met002_s.jpg"
        ];

        public function LoadImage2() {

            images = new Array(IMAGE_URL.length);

            for (var i:int = 0; i < IMAGE_URL.length; i++)
            {
                var loader:Loader = new Loader();
                loader.contentLoaderInfo.addEventListener(Event.INIT, init);
                loader.load(new URLRequest(IMAGE_URL[i]), new LoaderContext(true));
                loader.name = i.toString();
            }
        }

        private function init(event:Event):void
        {
            images[event.currentTarget.loader.name] = event.currentTarget.loader;
            if (++count == IMAGE_URL.length) completeHandler();
        }

        private function completeHandler():void
        {

            images[0].x = 0;
            images[0].y = 0;
            images[1].x = 60;
            images[1].y = 0;

            for (var i:int = 0; i < images.length; i++)
            {
                images[i].width = 60;
                images[i].height = 60;

                addChild(images[i]);

            }

            Tweener.addTween(images[0], {
                time: 5,    // 5秒間のアニメーション
                delay: 2.3,
                scaleX: 0.2,  // s の scaleX を 5 まで遷移
                scaleY: 0.2,  // s の scaleY を 5 まで遷移
                x: 0,
                y: 100
                //transition: "easeInBounce",
            });

            Tweener.addTween(images[1], {
                time: 5,    // 5秒間のアニメーション
                delay: 2,
                x: 180,
                y: 0
            });

        }
    }
}

参考サイト
第6回 動きのある Flash を作る(後編):プログラマのためのFlash遊び方|gihyo.jp … 技術評論社

参考の参考(Timerクラス)の使い方
第5回 動きのある Flash を作る(前編):プログラマのためのFlash遊び方|gihyo.jp … 技術評論社
FLASHとActionScript ActionScriptで画像を移動させる


4.flashvarsで、Flash実行時にパラメータを渡してみた

今回、WordPressのトップページにFlashを使おうとしています。WordPressのトップページのURLは、
http://URL/blog/

といった感じになるんですけど、実際のHTMLファイルがどこにあるかというと、
http://URL/blog/wp-content/themes/%5Bテーマ名%5D/

になる。これはテーマを切り替えてもトップページの見え方が変わらないように、マッピングをしているから。
ただ、これが原因で、ActionScriptの中で相対パスを使っていると問題が出てくる。相対パスで、img/met001_s.jpg と記載した場合、サーバ上にアップしたときに画像が読めなくなります。

自分のPC上でHTMLファイルを直接開いているときは、HTMLファイルからの相対パスに画像ファイルが存在するため、画像ファイルを読込めますが、WordPressのトップページで、相対パスを使ってimg/met001_s.jpgと指定した場合、WordPress上の
http://URL/blog/img/met001_s.jpg (ブラウザからみた相対パス)

を見に行くことになる。が実際のファイルはそこにはない。トップページ本体のHTMLファイルはURLマッピングされているが、そのほかの”部品”にあたるもの(画像ファイルとか、javascriptファイルとか)は、絶対パスで指定しておかないと読めない。WordPressの仕様と言っていいのか、当たり前の仕組みなのかよくわからないけど。

ActionScriptの中で、画像ファイルを絶対パスで指定させたいんだけど、開発環境(自分のPC)と商用環境(サーバ上)で当然のことながら絶対パスが違ってきます。なので、画像ファイルのディレクトリをソースコードに記載せず、外部定義することにした。
HTMLの中でFlashを呼び出すときに、パラメータflashvarsをつかって、Flashアプリに変数を引き渡すことができますので、これを使うことにします。

僕の場合、FlashDevelopを使いActionScriptのコーディングを行っているんですが、自動生成されるHTMLの中ではswfobject.jsを使ってFlashを呼び出しています。その中にflashvarsを書き込む場所があるので、そこにパラメータimg_dirを設定することにしました。

    <script src="js/swfobject.js"></script>
    <script>
        var flashvars = {
            img_dir: "./img"
        };
        var params = {
            menu: "false",
            scale: "noScale",
            allowFullscreen: "true",
            allowScriptAccess: "always",
            bgcolor: "",
            wmode: "direct" // can cause issues with FP settings & webcam
        };
        var attributes = {
            id:"blog"
        };
        swfobject.embedSWF(
            "blog.swf", 
            "altContent", "100%", "100%", "10.0.0", 
            "expressInstall.swf", 
            flashvars, params, attributes);
    </script>

次に、ActionScript側でflashvarsのパラメータを受け取るようにします。

flashvarsという配列変数(ハッシュですかね) に、引き渡された値がはいっています。flashvars[“img_dir”]として値を取得できます。

ソースコードの中で、直接img_dir:Stringを設定していた行を削除して、
private var img_dir:String = flashvars[“img_dir”];
に書き換えます

        private var flashvars:Object = loaderInfo.parameters;
        private var img_dir:String = flashvars["img_dir"];
        //private var img_dir:String = "./img";  // 単体テスト用

        private    const IMAGE_URL:Array =
        [
            img_dir + "/met001_s.jpg",
            img_dir + "/met002_s.jpg"
        ];

こうすることで、HTMLファイルの中で画像ファイルの置き場所を設定できるようになりました。WordPress上にアップするときは、以下のような形でHTMLの中のflashvarsの設定を変更しておけばOKになります。

var flashvars = {
img_dir: "http://URL/blog/wp-content/themes/[テーマ名]/[画像ファイル置き場所]"
};

ふぅ、長かった・・・