NORIのFlashユーザのためのMovable Type講座 gihyo.jp版

第8回Flashコンテンツを公開する

Flashコンテンツを公開するために今回は、MTでhtmlを出力します。

通常であれば、Flashが出力するhtmlでも十分かもしれません。しかし、今回はコンテンツ(写真画像やタイトル)をMTで管理しているので、 検索エンジン対策も兼ねてダイナミックに変化するhtmlを提供したいと思います。

これを実現するには、SWFObjectを使用して、Flashに置き換わる<div>要素の部分にも、情報を出力します。

また、今回のコンテンツは、フォトアルバムということで、個々の写真のURLを指定できるようにSWFAddressを利用します。

まず「SWFAddressの導入によるFlashの修正」をし、次は「MTによるSWFObjectを利用したhtmlの作成」について紹介します。

SWFAddressの利用

SWFAdressは、Flashとブラウザ間で、URLやタイトルの情報をやりとりする仕組みを提供します。

これを利用すると、Flashで次のことが可能になります。

  • アドレスバーの文字列を取得する(URLが変更されるとFlash内にイベントが流れます⁠⁠。
  • ブラウザのアドレスバーやタイトルを変更する。

今回のフォトアルバムでいえば、画像ごとにURLとタイトルを変更できます。 つまり個別の画像に対して、固有のタイトルでのブックマークが可能になります。

 個別のURLとタイトル
図 個別のURLとタイトル

SWFAdressは、以下で配布されていますので、ダウンロードしておきます。

 SWFAdressサイト
図 SWFAdressサイト

SWFAdressに対応したFlashを作成する際に、必要な機能は次の通りです。

  • アドレスバーが変更されたら、アドレスバーの文字列にしたがって画像を読み込む
  • アドレスバー、タイトルバー、ステータスバーをスクリプトで変更する。

大きな修正として、従来はXMLを読み込んでからFlash内部で関数を呼んで画像を表示していましたが、SWFAddressではアドレスバーの変更がすべてのきっかけになるため、アドレスバーの変更→XMLのチェック→画像の表示となります。

このとき重要なのは、XMLがまだ読み込み終わっていない場合を想定してロジックを組み立てないといけないことです。

また、クリックして次の画像を表示するフローが、クリックしたらアドレスバーを変更するフローに変わります。アドレスバーの変更はFlash内のイベントを呼び起こし、次の画像を読み込むというフローに繋がります。

アドレスバーの変更イベントは、一番最初にFlashを表示した時も発生します。

SWFAddressの準備

SWFAddressでは、2つのasファイルが提供されています。

今回作成しているFlashは、AS3なので、ダウンロードし解凍したフォルダのsrc/as/3にある2つのasファイルが必要です。

  • SWFAddress.as
  • SWFAddressEvent.as

とりあえず、Flaファイルと同じフォルダにコピーしておきましょう。

 2つのASは、同じフォルダに置く
図 2つのASは、同じフォルダに置く

では、URLを読み取る部分から作成しましょう。

URLの読み取り

SWFAddressでは、URLのアドレスが~.html#/○○となる場合の、○○をFlash側で知ることができます。

そこで、今回のフォトアルバムでは、次のような仕様にしています。

「URLを~.html#/<entryID>とし、ユーザが~.html/#1とアクセスすると、entryID=1の画像を表示する」

SWFAddrressでは、アドレスバーが変更されると SWFAddressEvent.CHANGE というイベントが発生します。

そこで、次のようにすることで関数onChangeSWFAddress()がその都度、実行されます。

SWFAddress.addEventListener(SWFAddressEvent.CHANGE, onChangeSWFAddress);

関数の引数であるSWFAddressEventの value には、#以降の文字列が入ってきます。

ここからentryIDだけを取り出して、前回まで使っていたshowPicture()という関数に渡すのですが、実は、showPicture()は順番を元に表示する画像を特定しているため、そのまま数値を渡してもエラーになってしまいます。

そこで、一度、showPicture()を実行する前にentryIDから順番を求めるshowPictureByID()関数を作成しました。

それを利用して、表示すべき画像を特定しています。

showPictureByID()という関数では、渡されたentryIDから、配列image_arrayの中にあるオブジェクト1つ1つと照らし合わせて順番を割り出すgetNumFromID()関数を実行しています。

そうすることで、アドレスバーのURLの#/以降にentryIDを指定すると、正しくentryIDの画像が表示されるようになります。

//SWFAddress で得られたID  (ex. "/8")
var givenID:String

// SWFAddressに変化があると呼ばれる関数
function onChangeSWFAddress(e:SWFAddressEvent) {
    givenID=e.value;
    //実際のURLを仮定してテスト
    //givenID="/8";
    //まだXMLが読み込み完了してなければ・・・常に最初は「そう」
    if (image_array.toString()=="") {
        //XML読み込み実行
        myLoader.load(myURLRequest);
    } else {
        //XMLの読み込みが完了していれば、画像をIDで指定する
        showPictureByID(givenID);
    }
}

//イベント設定
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, onChangeSWFAddress);

//id番号で指定すると、showPicture用のナンバーに置き換えて実行する
function showPictureByID(e:String):void {
    trace("showPictureByID",e);
    var num:uint;
    if (e!="/") {
        var t_array=e.split("/");
        num=getNumFromID(t_array[1]);
    } else {
        num=0;
    }
    try {
        showPicture(num);
    } catch (e:Error) {
        //showPictureの引数が不正な時用
        trace("e:",e.message);
    }
}
//IDから、num番号を探し出す
function getNumFromID(id:String):int {
    var len:uint=image_array.length
    for (var num:uint = 0; num<len; num++) {
        var targetObj=image_array[num];
        if (String(targetObj.id)==id) {
        //idと一致したら、numを使用するので、ループ処理から抜ける
            break;
        }
    }
    return num;
}

アドレスバーとタイトルの更新

次はFlash内部で画像をクリックした際に、画像とともに、URLアドレスとタイトルを変化させます。

アドレスバーにURLをセットするには、SWFAddress.setValue(id:String)を使用します。これは、アドレスバーの「#/」以降の内容をidの内容にします。そして、このSWFAddress.setValue()が、SWFAddressEvent.CHANGEを発生させることになります。そして、そのイベントハンドラにて画像を読み込んだり、XMLを読み込む処理を行います。

また、タイトルバーに文字列を設定するには、SWFAddress.setTitle(title:String)を使用します。

今回は、クリックで表示した画像のエントリータイトルを設定することにしました。

その部分は次のようになります。

function setAddressBar(id:uint):void {
   //アドレスバーにEntryIDを設定
   SWFAddress.setValue(String(id));
}
function setTitleBar(title:String):void {
   //タイトルバーの値をセット
   SWFAddress.setTitle(title);
}

ASまとめ

今回のSWFAddress対応のために、スクリプトを修正しています。

修正点は、主に次の関数です。

  • onLoaded()関数
  • showPicture()関数
  • nextPicture()関数

また、myLoader.load(myURLRequest);は、SWFAddressEvent.CHANGEのイベントハンドラ内に移動しています。

htmlへの組み込み

SWFAddressのhtmlへの組み込みはシンプルです。

<head>で、次のようにjsファイルをリンクしておきます。

サーバーには、swfaddress.jsをFTPするのを忘れないようにしてください。

<script type="text/javascript" src="swfaddress/swfaddress.js"></script>

SWFObjectの利用

SWFObjectは、JavaScriptがオフの場合やFlash Playerがない場合に代替htmlを表示する仕組みです。この代替部分は、id名がついた<div>でデザインします。

そこで、その<div>の中をMTで出力します。SWFObjectもダウンロードしておきます。これはjsファイルがメインになります。

SWFObjectはcode.google.comで入手可能
SWFObjectはcode.google.comで入手可能

今回使用しているSWFObjectはバージョン2.0で、上記ページのリンク先、code.google.comから入手できます。

<div>内容の作成

 Flashの代わりに表示されるサムネイル
図 Flashの代わりに表示されるサムネイル

タイトルとサムネイル、★の結果を並べました。以下には上から3件分のソースを示しました。

<h2><a href="http://www.3oclock.com/my_first_blog-gihyojp/#/9" title="お台場">お台場</a></h2>
<img src="http://www.3oclock.com/my_first_blog-gihyojp/assets_c/2009/03/2007-03-25-FromDaiba-thumb-100xauto-7.jpg" alt="お台場" /><br />
<img alt="Stars:3" src="images/r3.jpg" />

<h2><a href="http://www.3oclock.com/my_first_blog-gihyojp/#/8" title="銀座4丁目">銀座4丁目</a></h2>
<img src="http://www.3oclock.com/my_first_blog-gihyojp/assets_c/2009/03/2006-10-28-ginza-thumb-100xauto-6.jpg" alt="銀座4丁目" /><br />
<img alt="Stars:3" src="images/r3.jpg" />

<h2><a href="http://www.3oclock.com/my_first_blog-gihyojp/#/7" title="かくれんぼ">かくれんぼ</a></h2>
<img src="http://www.3oclock.com/my_first_blog-gihyojp/assets_c/2009/03/2006-11-10-park-thumb-100xauto-5.jpg" alt="かくれんぼ" /><br />
<img alt="Stars:5" src="images/r5.jpg" />

まず、このhtmlで今までに出てこなかったのは、サムネイルの作成方法ですが、サムネイルは、次のMTタグで作成できます。

<$mt:AssetThumbnailURL$>

このとき、widthまたはheightを指定してどのくらいのサイズのサムネイルかを指定しますが、今回は、横100ピクセルで統一したサムネイルを作成しています。

width、heightには、数値だけを指定してピクセル数を基準にしたり、scaleで実際のサイズの何パーセントという指定も可能です。

詳細は、テンプレートタグリファレンス:MTAssetThumbnailURLをご覧ください。

タイトルリンクの作成

タイトルは<mt:EntryTitle>で取得できます。

また、そのリンク先のURLは、~.html#/○○と○○の部分だけがダイナミックに変わることが、SWFAddressの仕様で決まっているため、次のように表現できます。

<a href="<$mt:BlogURL$>#/<$mt:EntryID$>">

<$mt:BlogURL$>は、このブログのトップページのフルパスを返します。

★を表示するimgタグ

一番仕組みが複雑なのは、★を表示する仕組みです。画像のsrcに使用されている、r1~r5.jpgの数字と★の数は連動しています。

前回、MTで★の数を計算するように作ったので、そこを利用して画像ファイル名を選びます。

その★の数を求める部分は、photo.xmlを作るテンプレート内にすでにありますが、再利用するために、その部分を、さらにテンプレートモジュールに分割します。

テンプレートモジュールとは、Flashでいう関数のようなものです。

ただし、関数と違い戻り値を設定できないので、テンプレートモジュール内で変数を設定するか、実際にHTMLを出力する必要があります。

今回は、前者の方法を使いました。

テンプレートモジュールの利用

テンプレートモジュールを呼び出すときは、次のようにします。

<$mt:Include module="テンプレートモジュール名"$>

テンプレートモジュールは、テンプレート一覧画面の中でも,下の方にあります。ここで、テンプレートモジュールを作成します。

 テンプレート一覧の画面
図 テンプレート一覧の画面

前回の★の数を求める部分をそのままを抜き出し、テンプレートモジュールにしました。

名前:makerating
<mt:Ignore>***********エントリー開始***********</mt:Ignore>
<$mt:SetVar name="result" value="0" $>
<mt:SetVarBlock name="count"><$mt:EntryCommentCount$></mt:SetVarBlock>
<mt:Comments>
<mt:SetVarBlock op="+" name="result"><$mt:CommentBody remove_html="1"$></mt:SetVarBlock>
</mt:Comments>
<$mt:SetVar name="result" op="/" value="$count"$>
<$mt:SetVar name="result" op="+" value="0.5"$>
<$mt:SetVarBlock name="result"><$mt:GetVar name="result" sprintf="%d"$></mt:SetVarBlock>
<mt:Ignore>***********以前作成したphoto.xmlのインデックステンプレート***********</mt:Ignore>

すると、photo.xmlを書き出すテンプレートではモジュール化した部分を呼び出して使用するため、次のようにできます。

photo.xmlを出力するテンプレート
<?xml version="1.0" encoding="utf-8"?>
<entries>
<mt:Entries>
<$mt:Include module="makerating"$>
<entry id="<$mt:EntryID$>" title="<$mt:EntryTitle$>" rating="<$mt:GetVar name="result"$>">
<mt:EntryAssets type="image">
<img src="<$mt:AssetURL$>" />
</mt:EntryAssets>
</entry>
<mt:Ignore>***********エントリー終了***********</mt:Ignore>
</mt:Entries>
</entries>

<$mt:Include module="makerating"$>が、テンプレートモジュール「makerating」を呼び出しているところです。また、テンプレートモジュール「makerating」の計算結果が変数「result」に残ります。この変数はテンプレートが終了しても残るため、呼び出した次の行で<$mt:GetVar$>を使用して値を取り出します。

photo.xmlだけでなく、HTMLの出力でも同じテンプレートを利用すると次のようになります(一部だけを抜粋⁠⁠。

そして、<$mt:Include$>の次の行では、変数「result」を、srcで指定する画像ファイル名の一部として使用しています。

<$mt:Include module="makerating"$>
<img alt="Stars:<$mt:GetVar name="result"$>" src="images/r<$mt:GetVar name="result"$>.jpg" />

htmlのテンプレートを作成

ここまでを整理しました。

<mt:Entries>
<h2><a href="<$mt:BlogURL$>#/<$mt:EntryID$>" title="<$mt:EntryTitle$>"><$mt:EntryTitle$></a></h2>
<mt:EntryAssets type="image">
<img src="<$MTAssetThumbnailURL width="100"$>" alt="<$mt:EntryTitle$>" />
<br />
</mt:EntryAssets>
<$mt:Include module="makerating"$>
<img alt="Stars:<$mt:GetVar name="result"$>" src="images/r<$mt:GetVar name="result"$>.jpg" />
</mt:Entries>

上記は、<div id="container">の部分に相当します。htmlとして必要な要素が他にもありますので、それらを追加します。

また、上記のhtml用テンプレートをさらに「サムネイルインデックス」という名前のテンプレートモジュールとして登録して、 次のようなインデックステンプレートを作成しました。

ファイル名:index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" id="sixapart-standard">
<head>
<$mt:Include module="HTMLヘッダー"$>
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="<$mt:Link template="rsd"$>" />
<title><$mt:BlogName encode_html="1"$></title>
</head>
<body id="<$mt:BlogTemplateSetID$>" class="mt-main-index <$mt:Var name="page_layout"$>">
<div id="container">
<$mt:Include module="サムネイルインデックス"$>
<p>Noriyuki ITO<br />Yokohama Japan<br />+81-45-972-3517</p>
</div>
</body>
</html>
テンプレートモジュール名:サムネイルインデックス
<mt:Entries>
<h2><a href="<$mt:BlogURL$>#/<$mt:EntryID$>" title="<$mt:EntryTitle$>"><$mt:EntryTitle$></a></h2>
<mt:EntryAssets type="image">
<img src="<$MTAssetThumbnailURL width="100"$>" alt="<$mt:EntryTitle$>" />
<br />
</mt:EntryAssets>
<$mt:Include module="makerating"$>
<img alt="Stars:<$mt:GetVar name="result"$>" src="images/r<$mt:GetVar name="result"$>.jpg" />
</mt:Entries>
テンプレートモジュール名:makerating
<mt:Ignore>***********エントリー開始***********</mt:Ignore>
<$mt:SetVar name="result" value="0" $>
<mt:SetVarBlock name="count"><$mt:EntryCommentCount$></mt:SetVarBlock>
<mt:Comments>
<mt:SetVarBlock op="+" name="result"><$mt:CommentBody remove_html="1"$></mt:SetVarBlock>
</mt:Comments>
<$mt:SetVar name="result" op="/" value="$count"$>
<$mt:SetVar name="result" op="+" value="0.5"$>
<$mt:SetVarBlock name="result"><$mt:GetVar name="result" sprintf="%d"$></mt:SetVarBlock>
<mt:Ignore>***********以前作成したphoto.xmlのインデックステンプレート***********</mt:Ignore>

SWFObjectをhtmlへ組み込む

SWFObjectをhtmlに組み込むときには、swfobject.jsとのリンクと、実際にswfを指定するJavaScriptの記述が必要です。

具体的には、次のように<head>内に記述します。

<script type="text/javascript" src="swfobject/swfobject.js"></script>
<script type="text/javascript">
   /*<![CDATA[*/
   swfobject.embedSWF('showPicture4.swf', 'container', '840', '840', '9.0.45', 
   'swfobject/expressinstall.swf', {}, {bgcolor: '#CCCCCC', menu: 'false', wmode: 'opaque'}, {id: 'showPicture'});
   /*]]>*/
</script>

詳細についてはマニュアルを参照ください。

上記をindex.htmlを出力するためのインデックステンプレートに組み込みます。

この中には、SWFAddressとSWFObjectへのリンク行なども入っています。

ファイル名:index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" id="sixapart-standard">
<head>
<$mt:Include module="HTMLヘッダー"$>
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="<$mt:Link template="rsd"$>" />
<title><$mt:BlogName encode_html="1"$></title>
<script type="text/javascript" src="swfobject/swfobject.js"></script>
<script type="text/javascript" src="swfaddress/swfaddress.js"></script>
<script type="text/javascript">
   /*<![CDATA[*/
   // swfobject.embedSWF('showPicture4.swf', 'container', '840', '840', '9.0.45', 
   'swfobject/expressinstall.swf', {}, {bgcolor: '#CCCCCC', menu: 'false', wmode: 'opaque'}, {id: 'showPicture'});
   /*]]>*/
   </script>
</head>
<body id="<$mt:BlogTemplateSetID$>" class="mt-main-index <$mt:Var name="page_layout"$>">
<div id="container">
      <$mt:Include module="サムネイルインデックス"$>
     <p>Noriyuki ITO<br />Yokohama Japan<br />+81-45-972-3517</p>
</div>
</body>
</html>

まとめ

最終回は、SWFAddressとSWFObjectを利用して、FlashコンテンツをWEBサイトに置く方法を紹介しました。

もっともシンプルなhtmlであれば、Flashのパブリッシュだけでも可能ですが、SWFAddressを利用することでFlashコンテンツの苦手な中身の状態をURLに反映させることもできます。

MTと連携しているからこそできるのは、たとえばFlashのバージョンが条件を満たさないとかJavaScriptオフになっているなど、Flashでの再生条件に一致しない場合のHTML作成です。

このhtmlを作成する1つの狙いは、Flashコンテンツであっても検索エンジンが検索しやすい状態を作成することにあります。

検索エンジンはJavaScriptをオフにした状態のページやFlashの中にあるテキストまでしか理解できないため、外部テキストなどで更新する場合は肝心の情報が検索対象になりません。

しかし、htmlにある画像のサムネイルとaltは検索も可能です。また、そこからリンクしているタイトルごとの固別URLはFlashでありながら、写真を指定して表示できます。

一番最初に紹介したように、MTとFlashが連携することで、携帯電話を使った更新など意外な広がりを持ちます。また、構築が安価で気軽に始められるのがこの組み合わせの利点です。

基本は、連載でお伝えしたとおりです。あとは、演出やデザイン、アイデアなどで飾り付けを行ってつくりあげていただければと思います。

最後にこの連載で作成したサンプルサイトMy First Blog gFLAファイル等です。

おすすめ記事

記事・ニュース一覧