HOME

システム開発の株式会社システックス

2010年02月17日

Ajax入門(Adobe Spryでスライドショー)

つづきまして

「Adobe Spry」(アドビ スプライ)を応用したスライドショーの実現例をご紹介しましょう。

Adobe Spry

【公式サイト】
・「Adobe Spry framework for AJAX」(英語)

【特徴】
Adobe Spry とは、Adobeが提供するAjax対応Javasciptです。

Adobe Spry の特徴は、比較的簡単に“XMLデータ”を扱える点にあります。
つまり、XMLデータのデータファイルを元にしたWebページを手軽に作ることができます。
PartyWeb」のスライドショー機能は、このAdobe Spry (「Photo Gallery Demos」)を応用しています。

なお、Adobe Spry は、スライドショー以外にも、いろんな動き・効果・演出を付けることができます。
具体的にどんなことができるのか?については、下記URLのデモページをご覧下さい。
・「Spry Demo Gallery

【ダウンロード】

(1) Adobe ID を入手する。

Adobe Spry をダウンロードするために、まず「Adobe ID」を作成する必要があります。
下記URLの「Adobe ID を作成」を押して、ご自分の Adobe ID を作成して下さい。(無料です。)
・「Adobe – サインイン

(2) Adobe Spry をダウンロードする。

公式サイトにて、右上の「Download vX.X」をクリックします。
この後、ログイン画面が表示された方は、(1)で作成した Adobe ID でログインしてください。
最新版をダウンロードする画面に遷移するので、下記のファイルをダウンロードして下さい。
・spry_X-X-X_YYMMDD.zip
ダウンロードしたzipファイルの中には、Adobe Spry 本体はもちろん、使い方を記したドキュメントやデモ用のHTMLファイルも含まれています。(ただし、英語です。)

【サンプルコード】

※ご注意※
各ファイルを保存する文字コードが異なると、ブラウザで見たときに文字化けすることがあります。
これを回避するために、下記の全てのファイルを同じ文字コード(UTF-8など)で保存することをオススメいたします。

≪SlideShowData.xml≫

<?xml version="1.0" encoding="utf-8"?>
<SlideData>
  <Slides>
    <Slide path="1.jpg" width="500" height="334" thumbpath="1_t.jpg" thumbwidth="75" thumbheight="50" caption="1枚目の写真です。"/>
    <Slide path="2.jpg" width="500" height="334" thumbpath="2_t.jpg" thumbwidth="75" thumbheight="50" caption="2枚目の写真です。"/>
    <Slide path="3.jpg" width="500" height="334" thumbpath="3_t.jpg" thumbwidth="75" thumbheight="50" caption="3枚目の写真です。"/>
  </Slides>
</SlideData>

≪SlideShow.html≫

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <title>サンプル</title>
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache">
    <meta http-equiv="Expires" content="Thu, 01 Dec 2000 00:00:00 GMT">
    <link href="SlideShow.css" type="text/css" rel="stylesheet">
    <script type="text/javascript" src="xpath.js"></script>
    <script type="text/javascript" src="SpryData.js"></script>
    <script type="text/javascript" src="SpryEffects.js"></script>
    <script type="text/javascript" src="galleryEx.js"></script>
    <script type="text/javascript">
        var dsPhotos = new Spry.Data.XMLDataSet("./SlideShowData.xml","SlideData/Slides/Slide");
    </script>
</head>
<body>
    <div id="Slideshow">
        <div id="Transport">
            <ul>
                <li><a href="#" onclick="StopSlideShow(); AdvanceToNextImage(true);" title="前へ" class="On"><span>前へ</span></a></li>
                <li><a href="#" onclick="if (!gSlideShowOn) StartSlideShow();" title="再生" class="Off" id="playButton"><span>再生</span></a></li>
                <li><a href="#" onclick="if ( gSlideShowOn) StopSlideShow();" title="停止" class="On" id="stopButton"><span>停止</span></a></li>
                <li><a href="#" onclick="StopSlideShow(); AdvanceToNextImage();" title="次へ" class="On"><span class="FontSpace">次へ</span></a></li>
                <li><span id="playLabel">再生中...</span></li>
            </ul>
            <div style="clear: both;">
            </div>
        </div>
        <div id="Middle">
            <table>
                <tr>
                    <td>
                        <div id="thumbnails" spry:region="dsPhotos">
                            <div spry:repeat="dsPhotos" onclick="HandleThumbnailClick('{ds_RowID}');" 
                                 onmouseover="GrowThumbnail(this.getElementsByTagName('img')[0], '{@thumbwidth}', '{@thumbheight}');" 
                                 onmouseout="ShrinkThumbnail(this.getElementsByTagName('img')[0]);">
                                <img id="tn{ds_RowID}" alt="" src="{@thumbpath}" width="24" height="24" />
                            </div>
                        </div>
                    </td>
                </tr>
            </table>
            <div style="clear: both;">
            </div>
            <div id="Slide">
                <div id="mainImageOutline">
                    <img id="mainImage" alt="" src="" />
                </div>
                <div id="Caption">
                    <span id="mainMessage"></span>
                </div>
            </div>
        </div>
        <div id="Footer">
        </div>
    </div>
</body>
</html>

≪galleryEx.js≫
galleryEx.js は、「Photo Gallery Demos」で使われている gallery.js を、今回のサンプル用に少し改良したものです。
gallery.js を改良した部分を抜粋します。(他は gallery.js と変わりません。)

/*
dsPhotos.addObserver(function(nType, notifier, data) {
    if (nType == "onPreLoad")
        StopSlideShow();
});
*/

function SetMainMessage(msg)
{
    var spn = document.getElementById("mainMessage");
    if (spn) {
        spn.innerHTML = msg;
    }
    var cap = document.getElementById("Caption");
    if (cap) {
        if (msg != "") {
            cap.style.display = "";
        } else {
            cap.style.display = "none";
        }
    }
}

function ShowCurrentImage()
{
    var curRow = dsPhotos.getCurrentRow();
    SetMainImage(curRow["@path"], curRow["@width"], curRow["@height"], "tn" + curRow["ds_RowID"]);
    SetMainMessage(curRow["@caption"]);
}

function StartSlideShow(skipTimer)
{
    gSlideShowOn = true;
    if (!skipTimer)
        SetSlideShowTimer();
    var playLabel = document.getElementById("playLabel");
    if (playLabel)
        playLabel.firstChild.data = "再生中...";
    var playButton = document.getElementById("playButton");
    if (playButton)
        playButton.className = "Off";
    var stopButton = document.getElementById("stopButton");
    if (stopButton)
        stopButton.className = "On";
}

function StopSlideShow()
{
    gSlideShowOn = false;
    KillSlideShowTimer();
    var playLabel = document.getElementById("playLabel");
    if (playLabel)
        playLabel.firstChild.data = "停止中";
    var playButton = document.getElementById("playButton");
    if (playButton)
        playButton.className = "On";
    var stopButton = document.getElementById("stopButton");
    if (stopButton)
        stopButton.className = "Off";
}

≪SlideShow.css≫

/* スライドショー */
div#Slideshow
{
    margin-top: 10px;
    margin-left: 5px;
}
div#Slideshow *
{
    padding: 0px;
    margin: 0px;
}

/* スライドショー:操作パネル */
div#Slideshow div#Transport
{
    font-size: 12px;
    line-height: 120%;
    text-align: center;
    width: 700px;
    height: 53px;
    background-color: #333333;
}
div#Slideshow div#Transport ul
{
    list-style: none;
    margin-left: 5px;
}
div#Slideshow div#Transport ul li
{
    float: left;
    margin-top: 5px;
}
div#Slideshow div#Transport ul li a.On
{
    display: block;
    float: left;
    color: #ffffff;
    width: 92px;
    height: 34px;
}
div#Slideshow div#Transport ul li a.Off
{
    display: block;
    float: left;
    color: #00ffff;
    width: 92px;
    height: 34px;
}
div#Slideshow div#Transport ul li span
{
    display: block;
    margin-top: 10px;
}
div#Slideshow div#Transport ul li span#playLabel
{
    display: block;
    color: #ffffff;
    margin: 18px 0px 0px 10px;
    font-size: 16px;
}

/* スライドショー:中間部分(サムネイル+スライド) */
div#Slideshow div#Middle
{
    width: 700px;
    background-repeat: repeat-y;
    padding: 0px;
    background-color: #333333;
}
div#Slideshow div#Middle table
{
    width: 700px;
    border-width: 0px;
}
div#Slideshow div#Middle table td
{
    text-align: center;
}

/* スライドショー:サムネイル */
div#Slideshow div#Thumbnails
{
    width: 400px;
    margin-left: auto;
    margin-right: auto;
    margin-top: 0px;
    margin-bottom: 0px;
}
div#Slideshow div#Thumbnails div
{
    position: relative;
    width: 24px;
    height: 24px;
    float: left;
    margin: 8px;
    padding: 0px;
    float: left;
    display:inline;
}
div#Slideshow div#Thumbnails img
{
    border-right: #404040 1px solid;
    border-top: #999999 1px solid;
    right: 0px;
    left: 0px;
    float: left;
    border-left: #404040 1px solid;
    width: 24px;
    border-bottom: #333333 1px solid;
    position: absolute;
    height: 24px;
    cursor: pointer;
    cursor: hand;
}
.selectedThumbnail {  border: solid 2px #ffcc00 !important; }
.inFocus {  border: solid 1px #ffcc00 !important; }

/* スライドショー:スライド */
div#Slideshow div#Slide
{
    margin-top: 5px;
    padding: 0px;
    text-align: center;
}
div#Slideshow div#mainImageOutline
{
    margin-top: 0px;
    margin-bottom: 0px;
    margin-left: auto;
    margin-right: auto;
    padding: 0;
    background-color: #333333;
    padding: 10px; 
    overflow: hidden; 
    width: 0px;
    height: 0px;
}
div#Slideshow img#MainImage
{
    width: 100%;
    height: 100%;
}
div#Slideshow div#Slide div#Caption
{
    padding-right: 11px;
    padding-left: 11px;
    padding-bottom: 10px;
    margin: 1px 0px 0px 0px;
    color: #ffffff;
    padding-top: 10px;
    background-color: #333333;
    text-align: left;
    font-size: 14px;
    width: 500px;
    margin-left: auto;
    margin-right: auto
}

/* スライドショー:フッター部分 */
div#Slideshow div#Footer
{
    width: 700px;
    height: 16px;
    background-repeat: no-repeat;
    background-color: #333333;
}

≪xpath.js≫
≪SpryData.js≫
≪SpryEffects.js≫
これら3つは、公式サイトからダウンロードしたものをそのまま使います。

サンプルコードの解説

Photo Gallery Demos」を元にしたサンプルコードです。

SlideShowData.xml では、<Slide>1つで、1つの画像データを表しています。
各属性は、下記を表しています。
・path … オリジナル画像へのパス
・width … オリジナル画像の幅(ピクセル)
・height … オリジナル画像の高さ(ピクセル)
・thumbpath … サムネイル画像へのパス
・thumbwidth … サムネイル画像の幅(ピクセル)
・thumbheight … サムネイル像の高さ(ピクセル)
・caption … 画像のキャプション(題名)

SlideShow.html を見ると、ちょっとコムズカシイHTMLになっていますが、ポイントは2つあります。

1つ目のポイントは、

<script type="text/javascript">
    var dsPhotos = new Spry.Data.XMLDataSet("./SlideShowData.xml","SlideData/Slides/Slide");
</script>

です。
これにより、SlideShowData.xml の画像データの集まり(配列)が、dsPhotos に読み込まれます。

2つ目のポイントは、

<div id="Thumbnails" spry:region="dsPhotos">
    <div spry:repeat="dsPhotos" onclick="HandleThumbnailClick('{ds_RowID}');" 
         onmouseover="GrowThumbnail(this.getElementsByTagName('img')[0], '{@thumbwidth}', '{@thumbheight}');" 
         onmouseout="ShrinkThumbnail(this.getElementsByTagName('img')[0]);">
        <img id="tn{ds_RowID}" alt="" src="{@thumbpath}" width="24" height="24" />
    </div>
</div>

です。

時折出てくる「spry:~」や「{~}」の部分が、Adobe Spry独自の構文です。

具体的な構文の説明は省きますが、上記のような記述をすることにより、dsPhotos に読み込まれた画像データの集まり(配列)が順番に読み出され、その度、<div> や <img> が出力されます。

SlideShowData.xml には、3つの <Slide> があるので、最終的には、

<div id="Thumbnails">
    <div onclick="HandleThumbnailClick('0');"
         onmouseout="ShrinkThumbnail(this.getElementsByTagName('img')[0]);"
         onmouseover="GrowThumbnail(this.getElementsByTagName('img')[0], '75', '50');">
        <img id="tn0" alt="" src="1_t.jpg" width="24" height="24">
    </div>
    <div onclick="HandleThumbnailClick('1');"
         onmouseout="ShrinkThumbnail(this.getElementsByTagName('img')[0]);"
         onmouseover="GrowThumbnail(this.getElementsByTagName('img')[0], '75', '50');">
        <img id="tn1" alt="" src="2_t.jpg" width="24" height="24">
    </div>
    <div onclick="HandleThumbnailClick('2');"
         onmouseout="ShrinkThumbnail(this.getElementsByTagName('img')[0]);"
         onmouseover="GrowThumbnail(this.getElementsByTagName('img')[0], '75', '50');">
        <img id="tn2" alt="" src="3_t.jpg" width="24" height="24">
    </div>
</div>

というHTMLが出力されることになります。

やってみると分かりますが、SlideShowData.xml の <Slide> を増減させたり、各属性の値を変えたりすると、スライドショーの内容を自由に変更することができます。(ただ、XMLデータとして構文が正しくないと動きませんので、ご注意下さい。)

【参照URL】
・「Spry Documentation」(英語)
 Adobe Spry のドキュメントです。

・「逆引きAdobe Spryリファレンス
・「逆引きAdobe Spryリファレンス(Spry pre release 1.6.1)
 「Adobe Spryで、こんなことができるのかな?」と思ったら、ご確認ください。

・「Adobe Edge: 2007年2月 「Ajax したい!」Web デザイナーのための Spry 集中講座

・「@IT – アドビのAjaxフレームワーク「Spry」を使ってみよう

終わりに

さて、3回にわたって、Ajax についてご紹介をさせて頂きましたが、いかがだったでしょうか?

Ajax対応Javascript の登場により、リッチなWebページ作成の敷居がグッと下がりました。
最近では、安定性も動作速度も増して、多くのWebサイトが、Ajax を利用したコンテンツを採り入れています。

もし、今回の「Ajax入門」で Ajax に興味を持って頂けたのなら、まずは、サンプルをダウンロードして、いろいろ試してみるところから始めてみることをオススメいたします。
今まで実現したくても難しそうでできなかったことが、意外にカンタンに実現できてしまうかもしれませんよ。

皆様のWebサイト作りに、今回の「Ajax入門」がお役に立てましたら幸いです。