jQueryで実装しています。
簡単な仕組みはとしては、
指定されたIDのUIタグの直下にあるLIタグをタイルのようにposition:absolute;で配置していきます。
全体の横幅とカラム数から、各カラムの横幅を計算。
タイルを配置する場所は、
X方向(left: Npx;)はカラムの横幅が固定なので、何番目のカラムかによって取得。
Y方向(top: Npx;)は各カラムのうち、縦幅が最も低い値がY方向になります。
とりあえずソース(きたなくてごめんなさい(ノД`)
※2011年7月16日 ソース変更
子要素がないと無限ループに入ってしまう不具合を修正しました。
※2011年7月12日 ソース変更
ランダムでに要素の表示させる方法を変更し、各要素の表示される間隔を一定にすることで、流れるように表示されていくようにしました。
また、表示アニメーションを変更できるようにしました。
$(function(){
/*
こんな感じで実行します。
この場合は、id="TILES"をターゲットに、3カラムで余白3px、
全てのアニメーションが終わるまで1000秒、表示方法はフェードインさせます。
*/
TILES("ul#TILES", 3, 3, 1000, "fadein");
});
var TILES = function(parent, clm, cellpadding, time, anime){
/*
ul#TILESを基準に、その直下のliタグをタイル状に表示させます。
parent … 親要素のULタグ
clm … カラムの数
cellpadding … 要素ごとの余白(px)
parent … 親要素のID
time … 全ての要素を表示させるまでの時間
anime … fadein | slidedown | cards
*/
/* default */
if(clm == undefined || clm == 0) var clm = 3;
if(cellpadding == undefined || cellpadding == 0) var cellpadding = 3;
if(parent == undefined || parent == '') var parent = "ul#TILES";
if(time == undefined) time = 600;
if(anime == undefined) anime = "slidedown";
// 親要素
var pr = $(parent);
// 子要素
var ch = $(parent+'>li');
// 親要素のcss変更
pr.css("position","relative");
// 子要素の数
chMx = ch.length;
//子要素があれば
if(chMx > 0) {
// 子要素のcss変更
ch.css({"list-style":"none inside","padding":0,"overflow":"hidden","margin":cellpadding,"position":"absolute"});
// 子要素を隠す
ch.hide();
// 変更するcss を格納
var css = new Array();
// 各列の高さを格納する配列
var y = new Array();
// カラムの数だけの配列作成
for(var i = 0;i < clm;i++) {y[i] = 0;}
var bW = pr.width();
var cW = Math.floor(bW/clm);
var top = 0, // css:top
left = 0, // css:left
r = 0, // 改行のチェック
c = 0; // 回数(カラム数ごとに初期化)
//子要素をループ
ch.each(
function(i, elem){
var eW = cW-cellpadding * 2;
// 横幅の統一 : 縦幅の取得より先に実行(横幅を変えると縦幅が変動するため)
$(elem).width(eW);
// 縦幅の取得(余白も含める)
var eH = $(elem).height()+(cellpadding * 2);
var n = 0;
// 全体の横幅を超えれば、改行フラグを立てる(1行目以降)
if(cW + left > bW && r == 0) {
r++;
}
// 1行目の処理
if(r == 0) {
y[c] += eH; // 各カラムの高さを配列に格納
} else {
// 2行目以降の処理
// 高さ配列から、最小の高さを求める
//縦幅が最も低いカラムを求める
//最初に1つ目のカラムだけ取得
left = 0;
top = y[0];
n = 0;
for(var q = 0;q < clm;q++) {
if(y[q] < top) {
left = q * cW;
top = y[q];
n = q;
}
}
//求めたカラムの高さを更新
y[n] += eH;
}
// 時間差を発生させる
// 計算適当です(笑
var n = chMx - i + 1;
if(anime == "cards") {
css[i] = {"elem":elem, "css":{"top":top,"left":left,"height":eH}};
$(elem).css({"display":"block","top":0,"left":0,"width":eW,"height":eW,opacity:1,"z-index":n});
} else if(anime == "fadein") {
css[i] = {"elem":elem, "css":{opacity:1}};
$(elem).css({"display":"block","top":top,"left":left,"width":eW,"height":eH,opacity:0});
} else {
// アニメーションさせる値を配列に格納(あとで一度に反映)
css[i] = {"elem":elem, "css":{opacity:1,"height":eH}};
// 初期CSS
$(elem).css({"display":"block","top":top,"left":left,"width":eW,"height":0,opacity:0.5});
}
// 現在の横幅更新
left += cW;
//カウントアップ
c++;
if(c > clm) c = 0;
});
//縦幅が最も高いのカラムを求める
//最初に1つ目のカラムだけ取得
top = y[0];
for(var q = 0;q < clm;q++) {
if(y[q] > top) {
top = y[q];
}
}
// 親要素の高さを設定
pr.height(top);
// ランダムに呼び出してCSSを反映
var i = css.length;
var arr = new Array();
var c = 0;
var t = Math.floor(time / chMx);
while(--i) {
var j = Math.floor(Math.random() * (i + 1));
arr[j] = j;
if(css[j] != undefined) {
delay = t * c;
var e = css[j];
$(e.elem).delay(delay).animate(e.css,{duration:240});
css[j] = undefined;
c++;
}
}
// 残った要素にCSSを反映
for (var i in css) {
if(css[i] != undefined) {
delay = t * c;
var e = css[i];
$(e.elem).delay(delay).animate(e.css,{duration:240});
c++;
}
}
}
};
記述ミスとか余計な部分があればご指摘頂ければ嬉しいです(ノД`)
後日追記:
“パネル風”と書いてましたが、よくよく考えてみたら”タイル状”ですね・・・。
変更しました(ノД`)
Pingback: トップページのデザインを変更しました | hlw.me