かつて 電脳麻将 では、画面要素の fade-in/out を jQuery の メソッド で行っていましたが、ver.1.4.2 でCSSの機能で行うように変更しています。
jQuery ではCSSの opacity の値をタイマーイベントで徐々に変更することで実装していたようです。これをCSSの transition を使用するように変更します。
例えば、ある要素に
transition: opacity 0.4s ease-in-out;
と指定すれば、opacity の値が変更されたときに 0.4s の時間をかけて ease-in-out の方法にしたがって表示に反映する値を変更します。opacity を 0 → 1 とすれば fade-in、1 → 0 とすれば fade-out の効果が得られる訳です。
電脳麻将のUIでは、CSSに以下の設定があることを前提に、@kobalab/majiang-ui のクラス Majiang.UI.Util で show/hide、fadeIn/fadeOut を実装しています。
.hide { display: none !important; } .fadeout { opacity: 0 !important; }
実装は以下の通りです。
/* * fadein.js */ "use strict"; module.exports = { show: node => node.removeClass('hide fadeout'), hide: node => node.addClass('hide fadeout'), fadeIn: node =>{ node.addClass('hide fadeout'); setTimeout(()=>{ node.removeClass('hide'); setTimeout(()=> node.off('transitionend') .removeClass('fadeout'), 20) }, 100); return node; }, fadeOut: node => node.on('transitionend', ()=> node.off('transitionend') .addClass('hide')) .addClass('fadeout'), }
- show
- display と opacity の値を元に戻し、要素を表示させます。
- hide
- display: none、opacity: 0 とすることで、要素を非表示にします。
- fadeIn
- いったん display: none、opacity: 0 と非表示にした後、100ms 後に display の値を元に戻し、さらに 20ms 後に transitionend のイベントハンドラを無効にして opacity の値も元に戻します。いったん非表示にすることで、fadeIn を連続して呼び出しても違和感ない表示になります。
- fadeOut
- まず、opacity: 0 とし、transitionend イベント発生後に display: none とします。transitionend イベントは transition で指定した方法で変化を表示し終えたときに発火します。つまり opacity: 0 に変化し終えた後に display: none とする訳です。
ここで注意すべきことは、hide/fadeOut のときのCSSの値は display: none、opacity: 0 ですが、show/fadeIn のときに両者に設定すべき値は不明だということです*1。なので本来の値は変更せず、CSSのクラス hide、fadeout を追加することで値を一時的に変更しています。クラスを剝ぎ取れば両者は本来の値に戻る訳です。
以下で実際の表示を確認できます。
*1:display: block、opacity: 1 に戻すのが正しい保証はありません