[HTML5] 要素をフェードアウト/フェードインする

指定したHTMLの要素を徐々に表示する「フェードイン」と、徐々に非表示にする「フェードアウト」をJavaScriptで実装します。


www.youtube.com

ここでは大きく2種類の方法を取り上げます。 HTML5から登場したWeb Animation APIを利用したものと、はるか以前から利用されてきたsetInterval利用する物です。IE11を対象としないのであれば前者の方が滑らかに動いてくれるのでおすすめです。

Web Animation API

大まかな原理

3Dアニメや動画編集ソフトを触ったことがある方にはお馴染みの「キーフレームアニメーション」がHTMLでも利用できます。

難しい話ではなく、以下の図でいう「開始位置」と「終了位置」を指定するだけで、その間の状態は機械が自動的に補完した状態でアニメーションしてくれるというものです。超楽ちん。

さらに以下の図のように中間地点を好きなだけ設けることが可能です。

このキーフレームアニメの機能を利用してフェードイン/フェードアウトを実装します。 結論から言うと次のJavaScriptになります。opacityで要素の透明度を調整することができます。opacityが1で完全に表示されている状態、0が非表示(透明)の状態を表します。

// 対象の要素を取得
const chara = document.querySelector("#chara1")

// アニメーションする
chara.animate(
    // キーフレーム
    [
      {opacity: 1},       // 最初の状態(表示)
      {opacity: 0}        // 最後の状態 (非表示)
    ],
    2000   // 2000ミリ秒の長さでアニメーションを実行
)

あとはこのコードに必要なオプションを足し、必要なタイミングで実行してやるだけです。

サンプル

デモ

実際に動いているデモを以下から確認いただけます。 miku3.net

  • 「フェードアウト」ボタンを押すと画像が徐々に消えていきます。
  • 画像が消えている状態で「フェードイン」ボタンを押すと画像が徐々に表示されます。

※画像は「ゆるドラシル」からお借りしました

ソースコード

デモページのソースコードです。animateのオプションを指定しないとアニメ終了後に最初の状態に戻ってしまう点にご注意ください。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>フェードイン/フェードアウト</title>
</head>
<body>

<h1>フェードイン/アウト</h1>
<p>animateを利用した方法</p>
<img id="chara1" src="chara.png">

<form>
  <button type="button" id="btn-fadeout">フェードアウト</button>
  <button type="button" id="btn-fadein">フェードイン</button>
</form>

<script>
const chara1 = document.querySelector('#chara1')

// フェードアウト
document.querySelector('#btn-fadeout').addEventListener('click', ()=>{
  chara1.animate(
    // キーフレーム
    [
      {opacity: 1},
      {opacity: 0}
    ],
    // オプション
    {
      duration: 500,      // アニメが終了するまでの時間(ミリ秒)
      fill: 'forwards'    // アニメ完了後に最初の状態に戻さない
    }
  );
})

// フェードイン
document.querySelector('#btn-fadein').addEventListener('click', ()=>{
  chara1.animate(
    // キーフレーム
    [
      {opacity: 0},
      {opacity: 1}
    ],
    // オプション
    {
      duration: 500,      // アニメが終了するまでの時間(ミリ秒)
      fill: 'forwards'    // アニメ完了後に最初の状態に戻さない
    }
  );
})
</script>
</body>
</html>

setInterval版

IE11に対応しないとならないような場合、残念ながらWebAnimationAPIは利用できませんので、setIntervalを用いた方法を取ったりします。

大まかな原理

CSSのopacityをJavaScript経由で操作すると透明度を指定できますのでこれを利用します。指定する値もWebAnimationAPIと同じですね。1で完全表示、0で非表示(透明)になります。

const elem = document.querySelector('#chara1')

// 完全に表示
elem.style.opacity = 1

// 半透明
elem.style.opacity = 0.5

// 透明
elem.style.opacity = 0

サンプル

デモ

実際に動いているデモを以下から確認いただけます。 miku3.net

  • 「フェードアウト」ボタンを押すと画像が徐々に消えていきます。
  • 画像が消えている状態で「フェードイン」ボタンを押すと画像が徐々に表示されます。

※画像は「ゆるドラシル」からお借りしました

ソースコード

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>フェードイン/フェードアウト</title>
</head>
<body>

<h1>フェードイン/アウト</h1>
<p>setIntervalを利用した旧来の方法</p>
<img id="chara1" src="chara.png">

<form>
  <button type="button" id="btn-fadeout">フェードアウト</button>
  <button type="button" id="btn-fadein">フェードイン</button>
</form>

<script>
// フェードアウト
document.querySelector('#btn-fadeout').addEventListener('click', ()=>{
  fadeOut("#chara1", 80, ()=>{
    console.log("done");
  })
})
// フェードイン
document.querySelector('#btn-fadein').addEventListener('click', ()=>{
  fadeIn("#chara1", 80, ()=>{
    console.log("done");
  })
})


/**
 * 要素をフェードアウトする
 *
 * @param {string} id
 * @param {number} time
 * @param {function} [callback]
 */
function fadeOut(id, time, callback=null){
  const elem = document.querySelector(id)
  let i = 1.0

  const timerid = setInterval( ()=>{
    // 透明度を下げる
    elem.style.opacity = i
    i -= 0.1

    // 完全に透明になったら終了
    if( i <= 0 ){
      clearInterval(timerid)
      if( typeof callback === "function" ){
        callback(elem)
      }
    }
  }, time)
}

/**
 * 要素をフェードインする
 *
 * @param {string} id
 * @param {number} time
 * @param {function} [callback]
 */
function fadeIn(id, time, callback=null){
  const elem = document.querySelector(id)
  let i = 0.0

  const timerid = setInterval( ()=>{
    // 透明度を上げる
    elem.style.opacity = i
    i += 0.1

    // 完全に表示されたら終了
    if( i >= 1.0 ){
      clearInterval(timerid)
      if( typeof callback === "function" ){
        callback(elem)
      }
    }
  }, time)
}
</script>
</body>
</html>

参考ページ