Pinterest風グリッドレイアウトを作ってみよう:jQuery×HTML5×CSS3を真面目に勉強(3)(4/4 ページ)
jQueryを使って、女性に人気の写真共有SNS、Pinterestのグリッドレイアウトを再現してみよう。
JavaScriptの実装4 - 各グリッドの幅を個別に設定できるようにする
ここまでは異なる高さのグリッドを並べるための実装でしたが、幅に関しては全て同じ幅に固定されていました。
そこで各グリッドに任意の値を指定することで異なる幅のグリッドを生成して並べられるようにカスタマイズしてみたいと思います。
実装方法を定義
幅を設定したいグリッドをどうやって指定するか、幅の基準はどうするかを決めます。なるべく手軽に指定できるようにしたいので、今回は次のようにします。
- 任意のグリッド要素のHTMLタグにdata属性を使って幅を設定する
- デフォルトのグリッド幅を基準として、基準となるグリッド1個分、2個分・・・、といったように指定する
HTML5には、HTMLの名前空間に属さないユーザーオリジナルの属性を定義する機能が備わっています。これを独自データ属性と呼びます。よく知らない、より詳しく知りたいという方は、こちらのページをご参照ください。
以下のように記述することで、任意のグリッド要素に幅を設定します。
<div class="grid" data-size="2">
<div class="imgholder">
<img src="http://media-cache-ec3.pinimg.com/192x/34/c5/e2/34c5e2172503fa9a5aa719ee4e541202.jpg">
</div>
<h2>3 | Photo title</h2>
<p>For a foster child who's been passed around from home to home, a little piece of hope is lost at each transition. This week, your support will give them a duffel ...</p>
<div class="meta">by Annie onto style.</div>
</div>
続いてJavaScriptです。主にグリッドを配置するロジックが以下のように変わります。
//gridが配置されるx座標値、y座標値を取得
var getGridPosition = function(size) {
if (size > 1) {
var arrayLimit = gridArray.length - size,
defined = false,
tempHeight;
for (var i=0; i<gridArray.length; i++) {
var obj = gridArray[i],
x = obj.x;
if (x >= 0 && x <= arrayLimit) {
var heightArray = getHeightArray(x, size);
if (!defined) {
defined = true;
tempHeight = heightArray;
tempHeight.x = x;
} else {
if (heightArray.max < tempHeight.max) {
tempHeight = heightArray;
tempHeight.x = x;
}
}
}
}
return tempHeight;
} else {
return getHeightArray(0, gridArray.length);
}
};
//gridを配置
var setPosition = function(grid) {
//check grid size
var size;
if (!grid.data('size') || grid.data('size') < 0) {
size = 1;
} else if (grid.data('size') > numOfCol) { // extra
size = numOfCol;
} else {
size = grid.data('size');
}
// gridの情報を定義
var pos = [];
var tempHeight = getGridPosition(size); // extra
pos.x = tempHeight.x;
if (size > 1) {
pos.y = tempHeight.max;
} else {
pos.y = tempHeight.min;
}
var gridWidth = colWidth * size - (grid.outerWidth() - grid.width()); // extra
// gridのスタイルを更新
grid.css({
'width': gridWidth - opts.offsetX * 2, // extra
'left': pos.x * colWidth,
'top': pos.y,
'position': 'absolute'
});
// gridArrayを新しいgridで更新
removeGridArray(pos.x, size);
pushGridArray(pos.x, pos.y, size, grid.outerHeight());
};
まず独自データ属性でサイズが指定されているかをチェックします。指定されていなければサイズ1とし、されていればその指定のサイズとします。ただし最大カラム数を超えたサイズが指定されていた場合は、最大カラム数と等しい値をサイズとして上書きします。
次にグリッドが配置されるx座標値とy座標値を取得します。今まではグリッドをカラム順序に沿った座標位置を取得するだけでしたが、グリッドにサイズが設けられたことにより、1行当たりの残りカラム数の幅にグリッドが収まりきるかどうかを判断する処理が必要になりました。収まるようならこれまで通りの座標値を取得し、収まりきらず改行して配置する必要がある場合は、そちらの座標値を取得するようにします。
また、指定されたグリッドのサイズに応じてwidth値も変化するため、それを算出する処理も1行加えます。
これで改修は終わりです。こちらから実際の動きを確認できます。
おわりに
従来とは一味違ったこのグリッドレイアウトは、Pinterestを始めファッション性の高いWebサイトでよく見かけます。以前このシリーズで紹介したパララックスエフェクト(関連記事)と並ぶトレンドだったといっても過言ではないでしょう。トレンドだっただけにこの手のレイアウトを実現するプラグインは探せばいくつか出てきますが、筆者としては自作することによってアルゴリズムを理解する良いトレーニングになったと思います。
今回作成したのは他に出回っているプラグインに比べていくらか機能の少ないシンプルなモノとなっていますが、もしご興味ある方がおりましたら、当ソースコードをフォークして、より高機能にカスタマイズしていただければ幸いです。
著者プロフィール
山田直樹(やまだ なおき)
クラスメソッドではたらくフロントエンド・エンジニア。JavaScript・HTML・CSSによる開発を主な生業とする一方、スタイリッシュかつクールなデザインを何よりも愛していることから、UIデザインを担当することもしばしば。実はプログラムよりも洋服を自作するのが一番得意だったりする。
Copyright © ITmedia, Inc. All Rights Reserved.

