今更ながら、格子状に並べたボックスをフェードイン・フェードアウトさせてみる
先日注文した冷凍イカが届いたので、これまでやったことがなかった下処理に挑戦中の kouraku です。
おはこんばんちわ。
さてさて今回は、JSを使って格子状に並べたボックスに対し、見た目簡単なフェードイン・フェードアウトのアニメーションを付けたいと思います。
なお、アニメーションは以下4種です。
- 順番通りにフェード
- 横にフェード
- 縦にフェード
- 斜めにフェード
HTML・CSS
100個のボックスを表示させるために、HTMLは以下のとおり組みます。
[HTML]
<div class="wrapper">
<button class="btnOrder">順番</button>
<button class="btnHorizon">横</button>
<button class="btnVertical">縦</button>
<button class="btnSlant">斜め</button>
<ul class="grid js-anim">
<li class="grid-item js-anim-item"><span></span></li>
: 100個分
<li class="grid-item js-anim-item"><span></span></li>
</ul>
</div>
上部各ボタンを押すと、それぞれフェードアニメーションが行われる想定です。
続いて、CSSは以下のとおり用意します。
[CSS(SCSS)]
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.wrapper {
max-width: 800px;
margin: 0 auto;
}
.grid {
display: flex;
flex-flow: row wrap;
margin: 0;
padding: 0;
list-style-type: none;
&-item {
opacity: 0;
width: 50px;
height: 50px;
margin: 5px;
transition: opacity 0.5s ease-in-out;
span {
display: block;
width: 100%;
height: 100%;
background: rgba(155,155,99,0.7);
transition: all 0.2s ease-in-out;
cursor: pointer;
&:hover {
transform: translate3d(0, -5px, 0);
box-shadow: 0 7px 5px -1px rgba(#000, 0.2);
}
}
}
&.animated {
.grid-item {
opacity: 1;
}
}
}
max-width: 800px の中に100個のボックスを格子状に並べるイメージです。
フェード効果は、.grid に .animated が付与されたら、opacity: 1 になる、という単純なものです。
ついでに、各ボックスをホバーすると、ボックスアニメーションするようにしてます。
今回のテーマではいらない要素ですが・・・(苦笑)
この状態で、例えば
$('button').on('click', function() {
$('.grid').toggleClass('animated');
});
とすれば、いずれかのボタンをクリックすると、全てのボックスが一斉にフェードイン・フェードアウトします。
時間差でフェードさせるには・・・?
順番にフェードアニメーションさせるには、各ボックスに対して transition-delay を与えれば可能です。
例えば、1個目は0s、2個目は0.05s、3個目は0.1s・・・といった具合で、0.05s ずつずらしていきます。
では、各種アニメーションを実現するための transition-delay 付与方法を考えていきます。
順番通りにフェード
こちらは単純。最初から最後まで順番に transition-delay を与えていけば良いですね。
例えば、こんな感じです。
$('.grid-item').each(function(index) {
var delay = 0.05 * index;
$(this).css({
'transition-delay': delay+'s'
});
});
横にフェード
ここからいきなり難易度が上がります。
考え方としては、まず .grid の幅に .grid-item が何個入るか、
言い換えると、1行辺り何列になるかを計算します。
あとは、各行の頭から終わりまで順番に transition-delay を与えます。
例えば、こんな感じです。
var $elm = $('.grid');
// ボックス1つ辺りの幅を取得
var $item = $('.grid-item');
var gridWidth = $item.width() + parseInt($item.css('margin-left')) + parseInt($item.css('margin-right'));
// 1行辺り何列かを計算
var maxCol = Math.floor($elm.width() / gridWidth);
// 現在の列数と1行辺りの列数の余剰で transition-delay を計算
$item.each(function(index) {
var column = Math.floor(index % maxCol);
var delay = 0.05 * column;
$(this).css({
'transition-delay': delay + 's'
});
});
縦にフェード
考え方は、横にフェードと同じです。1行辺り何列か。
あとは、行毎に transition-delay を与えます。
例えば、こんな感じです。
var $elm = $('.grid');
// ボックス1つ辺りの幅を取得
var $item = $('.grid-item');
var gridWidth = $item.width() + parseInt($item.css('margin-left')) + parseInt($item.css('margin-right'));
// 1行辺り何列かを計算
var maxCol = Math.floor($elm.width() / gridWidth);
// 現在の列数と1行辺りの列数の除数で transition-delay を計算
$item.each(function(index) {
var row = Math.floor(index / maxCol);
var delay = 0.05 * row;
$(this).css({
'transition-delay': delay + 's'
});
});
斜めにフェード
さて、最後の斜めはどの様に考えれば良いでしょうか。実はものすごく簡単です。
横にフェードを使用して、1行毎に1列分の transition-delay を加算してずらせば良いのです。
例えば、こんな感じです。
var $elm = $('.grid');
// ボックス1つ辺りの幅と高さを取得
var $item = $('.grid-item');
var gridWidth = $item.width() + parseInt($item.css('margin-left')) + parseInt($item.css('margin-right'));
// 1行辺り何列かを計算
var maxCol = Math.floor($elm.width() / gridWidth);
// 現在の列数、行数を加算して transition-delay を計算
$item.each(function(index) {
var column = Math.floor(index % maxCol);
var row = Math.floor(index / maxCol);
var delay = 0.05 * column + 0.05 + row;
$(this).css({
'transition-delay': delay + 's'
});
});
では、最終的にCodePenにまとめましたので、動作を確認しましょう。
See the Pen グリッドのアニメーション(フェードイン・フェードアウト) by bashalog (@bashalog) on CodePen.
まとめ
「斜めにフェード、ってどうやれば良いんだろう?」
そんなふとした思いからちょっと考えてみました今回のアニメーション。
簡単なところから1個1個進めていくと、意外にもシンプルな作りでできることがわかりますね。
ということで、今回の今更・・・はここまでです。
にしても、イカの下処理とか準備とか・・・初めてだと加減がさっぱりわからなくて難しいですね。。。
1杯目はハラワタを見事に傷つけてしまい、足には塩を振りすぎて見事に失敗。。。
次こそうまくやりたいところです。