Flashの初期設定パラメータにHTMLを使う

Flash非対応デバイスを気にしなきゃならないこのご時世、Webデザインやるときは、Flashコンテンツの代替として、HTMLの代替画像と最低限のJavascriptアニメーションがあって当然って感じになってきました。それどころかむしろ逆に、HTMLとJavascriptだけでコンテンツは成立しているんだけど、よりリッチなお化粧にFlashを追加する、という流れになる場合も多いでしょう。

でも作りを二重化すると、こんどは、顧客のプロモーションサイクルの都合なんかで、リンクや画像が変更になったとき、いちいち、HTMLとFlashを同じように修正/再パブリッシュしなきゃいけないのですごく面倒です。Flashの作りをパラメータ的に設計して対応? そうですね。でも、HTML用とFlash用の二箇所を変更しなきゃならないのは同じ。

そもそも、同じことを二箇所に書いてるのが原因です。それなら、「FlashがHTMLに書かれた内容をもとにして初期化される」ようにしたらどうでしょう?

ものは試しでやってみます。

サイトの入口に、新商品などの看板ビジュアルが置いてあるケースを考えます。この看板を、5秒で切り替わるスライドショーにしたとしましょう。

Flashは後回しで、まずは、HTMLとJavascriptだけでどうにか成立しているものを作ることにします。

<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    var curr = 0;
    setInterval(function(){
        $('#billboard .screen' + curr).fadeOut();
        curr = (curr + 1) % 3;
        $('#billboard .screen' + curr).fadeIn();
    }, 5000);
});
</script>

<div id="billboard">
    <div class="screen0" style="display:block;"><a href="./pr0/"><img src="img/screen0.jpg" alt=""></a></div>
    <div class="screen1" style="display:none;" ><a href="./pr1/"><img src="img/screen1.jpg" alt=""></a></div>
    <div class="screen2" style="display:none;" ><a href="./pr2/"><img src="img/screen2.jpg" alt=""></a></div>
</div>

こんな感じ。screen0〜2がクロスフェードで切り替わり。

これをベースにFlashでお化粧します。FlashPlayerが動く環境なら、もっとリッチなトランジションになります、って言うと、お客さんは大喜びです。(シー!! ホントに要るのかどうかは聞かないように。たいていの客先では、Flashイコールご立派ということになっているので。)

FlashVarsでリンク先と画像を受け取れるよう、パラメタライズしますよね。で、Javascript内にFlashVars用のパラメータ書きますよね。

var flashvars = {
    screen0_href: "./pr0/",
    screen0_imgsrc: "img/screen0.jpg",
    ...
}

おっと、これって書くの二回目じゃないですか? HTMLの中にすでに書いてありません? しかも、すでにjQuery使ってます。jQueryなら、DOMから欲しいものをワンライナーで拾ってくることができるじゃないですか!

var flashvars = {
    screen0_href: $('#billboard .screen0 a').attr('href'),
    screen0_imgsrc: $('#billboard .screen0 a img').attr('src'),
    ...
}

というわけで、Flashお化粧版のコードは、こんなふうになりました。

<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/swfobject.js"></script>
<script type="text/javascript" src="js/jquery.swfobject.1-1-1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    if($.flash.available) {
        // Replace HTML billboard to Flash
        $('#billboard').flash({
            swf: 'billboard.swf',
            width: 960,
            height: 300,
            flashvars: {
                screen0_href: $('#billboard .screen0 a').attr('href'),
                screen1_href: $('#billboard .screen1 a').attr('href'),
                screen2_href: $('#billboard .screen2 a').attr('href'),
                screen0_imgsrc: $('#billboard .screen0 a img').attr('src'),
                screen1_imgsrc: $('#billboard .screen1 a img').attr('src'),
                screen2_imgsrc: $('#billboard .screen2 a img').attr('src')
            }
        });
    }
    else {
        var curr = 0;
        setInterval(function(){
            $('#billboard .screen' + curr).fadeOut();
            curr = (curr + 1) % 3;
            $('#billboard .screen' + curr).fadeIn();
        }, 5000);
    }
});
</script>

<div id="billboard">
    <div class="screen0" style="display:block;"><a href="./pr0/"><img src="img/screen0.jpg" alt=""></a></div>
    <div class="screen1" style="display:none;" ><a href="./pr1/"><img src="img/screen1.jpg" alt=""></a></div>
    <div class="screen2" style="display:none;" ><a href="./pr2/"><img src="img/screen2.jpg" alt=""></a></div>
</div>

コンテンツの保守するのに、HTMLしか触らなくていいようになりました。HTMLがデザインの表現物であると同時に、XPathで値を取り出して来れるXML設定ファイルみたいです。

HTMLの属性で済ませられれば、サーバサイド生成で制御してもらうのも簡単です。JavascriptのコードをPHPで吐き出すのは頭沸いてしまいますが、HTMLならどんなテンプレートエンジンでも朝飯前ですしね。

あと図らずもこれ、「Flashでしかアクセスしないリソースはブラウザの更新ボタンが通じない」という問題にも対処できるものになっています。ブラウザの更新ボタンをクリックすると、"img/screen0.jpg" などが先にリクエストされ、そのあとでswfがロードされます。ブラウザの更新ボタンをクリックしたときは、swfが画像をロードするかなり前に、その画像ファイルのキャッシュステータスが更新されてることに。