私家版imageFlowのメモ。

iTunesの「CoverFlow」のように画像を表示できるスクリプト「imageFlow」を自分用にカスタマイズ。

★本家はコチラから → imageFlow 0.9
★本家はこちら → ImageFlow (サイト移転しているようです。2008.11.01追記)

主な変更点は次の通り。
  • 画像ギャラリーの下に、その画像の説明文を表示できるエリアを増設。
    • それに伴って、imgタグのオプション属性(alt,longdesc,title)に設定する内容を変更。(詳細は後述)
  • 最前面の画像をクリックしたときの挙動を変更。
    • alt属性に設定されたURLを、ブラウザの新ウィンドウ(タブ)で開くように変更。
  • 読み込む画像のURL、説明文の場所などを外部の設定ファイルに記述。そのファイルを読み込んで画像を表示。
  • GETメソッドで各種パラメータを渡す仕様に変更。
    • reflect.php(画像に反射エフェクトを加えるスクリプト)の ON / OFF。
    • 設定ファイルを読み込むか、画像ディレクトリを指定してその中の画像ファイルを全て読み込むかの切り替え。
    • 設定ファイル(又は画像ディレクトリ)の場所を指定。
サンプルはこんな感じ↓。



iframeを使ってこのページに読み込んでいます。
iframeの中身を差し替えることによって、いくつかのギャラリーを切り替えることも可能。この動作を可能にするために、GETメソッドでパラメータを渡す方式にしてみたのです。ギャラリー切り替えのサンプルはコチラ。左側の日付をクリックすると、ギャラリーが切り替わります。

RSSで最新売れ筋アイテムをチェック!

具体的な変更点。
imageFlowで画像を表示するページに、次の領域を追加。

<!-- ここから imageFlow -->
<div style="width:500px;">
<div id="imageflow">
   <div id="loading">
       <b>Loading images</b><br/>
       <img src="loading.gif" width="208" height="13" alt="loading" />
   </div>
   <div id="images">
        <img src="画像ファイルのURL" longdesc="この画像の説明ファイルの場所" title="画像のタイトル" alt="画像クリック時にジャンプするURL" />
       <img src="画像ファイルのURL" longdesc="この画像の説明ファイルの場所" title="画像のタイトル" alt="画像クリック時にジャンプするURL" />
      <!-- 以下、画像ファイルを読み込むだけ<img ...>を記述。-->
      
   </div>
   <div id="captions"></div>
   <div id="scrollbar">
     <div id="slider"></div>
   </div>
   <div id="details"></div>
</div>

id="details"として作成したdiv領域のスタイルを設定するために、screen.cssに以下の記述を追加。

#details{
  font-size:10pt;
  color:#fff;
  background-color:#000;
  margin-top:40px;
  margin-left:5px;
  margin-right:5px;
  border-color:#eee;
  border-width:1px;
  border-style:dotted;
}

で、このスクリプトの本体「imageflow.js」。
オリジナルでは、imgタグのalt属性に画像のキャプションを、longdesc属性には画像クリック時のジャンプ先URLを、それぞれ格納してimageflow.jsに渡していましたが、以下のように変更。
alt属性に、画像クリック時のジャンプ先URL
★longdesc属性に、説明文ファイルの場所
★title属性に、画像のキャプション

更に、画像をクリックしたときの挙動を弄ったので、そこも変更。

・imageflow.jsの38行目あたりに1行追加
var conf_details = 'details';

・同じく89行目あたりに追加
/*  detailsエリアに説明文テキストを読み込み  */
loadTextFile( img_div.childNodes.item(array_images[caption_id]).getAttribute('longdesc') );

関数「loadTextFile()」は、別ファイルに記述。内容は後述。

・169行目を変更(ジャンプ先を別窓で開くように)
image.onclick = function() { document.location = this.url; }
  ↓↓
image.onclick = function(){window.open( this.getAttribute("alt"));}

・186行目あたりに追加。
details_div = document.getElementById(conf_details);

・215行目の後に追加。
/* Set details attributes */
details_div.style.width = images_width - 20 + 'px';

・254行目から2行変更。
image.url = image.getAttribute('longdesc');
image.ondblclick = function() { document.location = this.url; }
  ↓↓
image.url = image.getAttribute('alt');
image.ondblclick = function(){ window.open( this.getAttribute("alt"));}


detailsエリアに説明文を読み込むための関数を作る。imageflow.jsとは別ファイル「xmlhttp.js」に記述。

/*******    xmlhttp.js     **********                                            */
/*  非同期通信を用いてテキストエリアに説明文を表示            */
/*  2008.06.25                       */

function createXMLHttpRequest(cbFunc){
   var XMLhttpObject = null;
   try{
       XMLhttpObject = new XMLHttpRequest();
   }catch(e){
     try{
        XMLhttpObject = new ActiveXObject("Msxml2.XMLHTTP");
     }catch(e){
        try{
          XMLhttpObject = new ActiveXObject("Microsoft.XMLHTTP");
        }catch(e){
          return null;
        }
     }
   }
  if (XMLhttpObject) XMLhttpObject.onreadystatechange = cbFunc;
  return XMLhttpObject;
}

function loadTextFile(fName){
   // document.getElementById("details").innerHTML += "here";     //test

    httpObj = createXMLHttpRequest(displayData);
    if (httpObj){
        httpObj.open("GET",fName,true);
        httpObj.send(null);
    }
}

function displayData(){
  if ((httpObj.readyState == 4) && (httpObj.status == 200)){
    document.getElementById("details").innerHTML = httpObj.responseText;    // ファイルを表示するエリアを指定
  }else{
    document.getElementById("details").innerHTML = "......";
  }
}

エラー処理などしていないので注意。

そしてimageFlowを表示するHTML。
上の方で例示したように、<div id="image">〜</div>の中に<img 〜>タグをガシガシ記述して行けばよいのだが、面倒である。加えて、画像ギャラリーの切り替えにも簡単に対応したい。ということで、HTMLの例。

<html>
<head>
    <title>ImageFlowのサンプル</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="language" content="ja" />

<link rel="stylesheet" title="Standard" href="screen.css" type="text/css" media="screen" />
<script language="JavaScript" type="text/javascript" src="xmlhttp.js"></script>
<script language="JavaScript" type="text/javascript" src="imageflow.js"></script>

</head>
<body style="width:500px;height:500px;">

<!-- ここから imageFlow -->
<div style="width:500px;">
<div id="imageflow">
    <div id="loading">
        <b>Loading images</b><br/>
        <img src="loading.gif" width="208" height="13" alt="loading" />
    </div>
    <div id="images">

<?php
$read_method = htmlspecialchars($_GET['m']);     // 1: 画像ディレクトリから読み込み    2: 画像リストファイルを読み込み
$reflect_flag = htmlspecialchars($_GET['r']);         //  0: reflect.php をスルー      1 : reflect.phpを呼ぶ
 
// 引数dで、読み込むリストファイルを指定。
$d = htmlspecialchars($_GET['d']);
switch  ($d){
   case  1:     //sample
     $img_dir = "../sample/sample.txt";
     break;
   case 0:
     $img_dir = "./img";
     beak;     
   case 2:   //200710_1
     $img_dir = "../sample/200710.txt";
     break;

}

if( $read_method == 1){                       //指定したディレクトリ内の画像ファイルを全て読み込む。
  if ($handle = opendir($img_dir)) {
    $file_array = scandir($img_dir);
    $max = count($file_array);
   
    for ($i = 0 ; $i < $max ; $i++){
        $file = $img_dir . '/'.$file_array[ $i ];
        if ( eregi( 'gif$',$file) or eregi( 'jpg$',$file) or eregi('jpeg$',$file) or eregi('png$',$file)){  //画像ファイルなら表示。そうでないなら何もしない。
          if( !$reflect_flag){
            print '<img src="'.$file.'" alt="http://freefielder.jp" title="画像" longdesc="'.$file.'.txt"/>';  
          }else{
              print '<img src="reflect.php?img='.$file.'" longdesc="'.$file.'.txt" title="" />';
          }
        }
    }
  }
}else{                         //リストファイルを読み込む。
 
 if ($handle = fopen( $img_dir , 'r')){
     while ( !feof( $handle ) ){
        $file = trim( fgets( $handle ) );             //リストの一行目は画像ファイル名(相対パス)
        $alt = trim( fgets( $handle ) );             //同じく二行目は画像クリック時のジャンプ先URL
        $title = trim( fgets( $handle ) );            //三行目は画像のキャプション
        $longdesc = trim( fgets( $handle ));    //四行目は説明文ファイルの場所(相対パス)
        if ( !$reflect_flag){
            print '<img src="'.$file.'" alt="'.$alt.'" title="'.$title.'" longdesc="'.$longdesc.'"/>';  
        }else{
            print '<img src="reflect.php?img='.$file.'" longdesc="'.$longdesc.'" title="'.$title.'" alt="'.$alt.'" />';
       }
     }
   }
   fclose( $handle);
 }

?>
    </div>
    <div id="captions"></div>
    <div id="scrollbar">
        <div id="slider"></div>
    </div>
    <div id="details"></div>
</div>
</div>
<!-- ここまでimageFlow -->
</body>
</html>


これを
http://yourAddress/sample.php?m=2&r=1&d=1
なんて感じでアクセスすると、d=1 で記述したリストファイルを読み込んで、reflectエフェクトをかけて表示する...ということになる。

画像リストファイルのフォーマットは以下の通り。
文字コードはUTF-8、改行はLF。
4行でひとまとめ。最終行のおしりには改行コードは不要。

ひとつめの画像ファイルの相対パス(例:./pics/001.jpg)
クリック時のジャンプ先URL(例:http://freefielder.jp/)
画像のキャプション
この画像の説明ファイルの場所(例:./details/001.txt)
ふたつめの画像ファイルの相対パス
 ・
 ・
 ・

画像の説明ファイルは、文字コードUTF-8のテキストファイル。
htmlタグも使用可能。

ということで。

2008.09.15追記:
Movable Typeを4.21にしたら、どうも動作不良。スクリプトのどこかがmt.jsとぶつかっているっぽいのだが、勘違いかもしれない。とりあえず、imageflowを動かすページではmt.jsを読み込まないようにしたら、ちゃんと動作します。


カテゴリ: