フロントエンドWebデザイン

HTML+CSS+JSで任天堂Switchのサウンドロゴアニメを作る

nintendoswitch フロントエンド

任天堂SwitchのCMのサウンドロゴアニメをHTMLとCSSとJSで作りました。
「カチャッ!」の音とコントローラーの動きとを合わせたつもりですが、通信速度によってはズレがあるかもです…。
優しい気持ちで見てもらえると嬉しいです。

任天堂Switch サウンドロゴアニメ サンプルコード

音声を自動再生に設定するとブラウザに怒られるので、左上の「再生する」ボタンを押すと動くようにしています。

See the Pen nintento switch sound by kenyo_c (@kenyo_c) on CodePen.

コード解説

HTML解説

HTMLでは以下の3つの要素をコーディングしていきます。

  1. 自動再生を切り替えるボタン
  2. ニンテンドーのロゴを表示させるためのdiv要素
  3. ロゴの下の「Nintendo」の文字
<div id="button-wrap">
  <button id="play-button" class="button-border"><span>再生する</span></button>
</div>
<div id="container" class="hidden">
  <div id="logo">
    <div id="left"></div>
    <div id="right"></div>
  </div>
  <span>Nintendo</span>
</div>

1.自動再生を切り替えるボタンは、「div要素」で「button」タグを囲んでいます。

<div id="button-wrap">
  <button id="play-button" class="button-border"><span>再生する</span></button>
</div>

2.ニンテンドーのロゴを表示させるためのdiv要素は、まずは大きなブロックid="container"で囲み、その中にロゴブロックid="logo"を用意します。
そして、コントローラーの右id="right"と左id="left"を用意します。

<div id="container" class="hidden">
  <div id="logo">
    <div id="left"></div>
    <div id="right"></div>
  </div>
  /* 最後に <span>Nintendo</span> をこの行に追記するよ */
</div>

3.ロゴの下の「Nintendo」の文字を、ロゴブロックid="logo"の下に追加します。

<span>Nintendo</span>

CSS解説

CSSはSCSS記法になっています。
コントローラーの上から落ちてくる動き、ボタンを押下した時の動きなどもCSSで指定いきます。

/* web fontを読み込み */
@import 'https://fonts.googleapis.com/css2?family=Rubik+Doodle+Shadow&display=swap';

/* すべての要素、html, body要素へのスタイル指定 */
* {
  box-sizing: border-box;
  outline: none;
}

html, body {
  height: 100vh;
  padding: 0;
  margin: 0;
  overflow: hidden;
  font-family: 'Rubik Doodle Shadow', sans-serif;
  background: #D20013;
}

/* スイッチロゴの表示切替え用CSS */
.hidden {
  display: none;
}

/* ボタンのデザイン */
.button-border {
  position: absolute;
  top: 5vmin;
  left: 5vmin;
  padding: 0;
  background: none;
  border: none;
  transition: all 0.3s;
  
  span {
    position: relative;
    display: block;
    padding: 1rem;
    font-weight: 600;
    color: #000;
    background: #FFF;
    border: 2px solid #000;
    border-radius: 0.5rem;
  }

  &::before {
    position: absolute;
    bottom: -8px;
    left: 0;
    box-sizing: border-box;
    display: block;
    width: 100%;
    height: 14px;
    content: "";
    background: #FFF;
    background-image: repeating-linear-gradient(
      -45deg,
      #000,
      #000 1px,
      transparent 2px,
      transparent 5px
    );
    background-size: 7px 7px;
    border: 2px solid #000;
    border-radius: 0 0 0.5rem 0.5rem;
    transition: all 0.3s;
    backface-visibility: hidden;
  }
  
  &:hover {
    transform: translate(0, 3px);
    &::before {
      bottom: -5px;
    }
  }

  &:active {
    transform: translate(0, 7px);
    &::before {
      bottom: -1px;
    }
  }
}

/* スイッチロゴを包括するブロックとNINTENDOのテキスト配置 */
#container {
  position: relative;
  top: 50%;
  left: 50%;
  float: left;
  transform: translate(-50%, -50%);

  > span {
    position: relative;
    left: 50%;
    float: left;
    margin-top: 7vmin;
    clear: both;
    font-size: 6.5vmin;
    color: #FFF;
    text-transform: uppercase;
    letter-spacing: 2vmin;
    transform: translateX(-50%);
  }
}

/* スイッチロゴの上から落ちてくる動き */
@keyframes slide-motion {
  0% {
    margin-top: -15vmin;
  }

  30% {
    margin-top: -17vmin; 
  }

  100% {
    margin-top: 0;
  }
}

/* スイッチロゴ */
#logo {
  position: relative;
  float: left;
  width: 55vmin;
  height: 55vmin;
  clear: both;

  #left, #right {
    position: relative;
    width: 47.5%;
    height: 100%;
    border: 4vmin solid #FFF;

    &::before {
      position: absolute;
      left: 50%;
      display: block;
      width: 60%;
      height: 0;
      padding-bottom: 60%;
      margin-left: -30%;
      content: '';
      border-radius: 50%;
    }
  }
  
  #left {
    float: left;
    border-top-left-radius: 17vmin;
    border-bottom-left-radius: 17vmin;

    &::before {
      top: 7vmin;
      background: #FFF;
    }
  }
  
  #right {
    float: right;
    margin-top: -15vmin;
    background: #FFF;
    border-top-right-radius: 17vmin;
    border-bottom-right-radius: 17vmin;
    animation: 0.3s slide-motion 1s linear forwards;

    &::before {
      bottom: 15vmin;
      background: #D20013;
    }
  }
}

cssは長くなってしまったのでざっくり解説になります。

全体に関するスタイル指定

まずは「NINTENDO」の文字をかわいいフォントにしたかったのでgoogleウェブフォントを読み込んで、html, body要素font-familyを指定してあげます。今回は'Rubik Doodle Shadow'を使っています。(読み込みできない時用にsans-serifも指定します。)

font-familyの指定の仕方についての解説はこちらの記事をどうぞ。

/* web fontを読み込み */
@import url('https://fonts.googleapis.com/css2?family=Rubik+Doodle+Shadow&display=swap');
/* すべての要素、html, body要素へのスタイル指定 */
* {
  box-sizing: border-box;
  outline: none;
}

html, body {
  height: 100vh;
  padding: 0;
  margin: 0;
  overflow: hidden;
  font-family: 'Rubik Doodle Shadow', sans-serif;
  background: #D20013;
}

左上ボタンのスタイル指定

ボタンはtransitionを使い、マウスホバー・マウスアウトした時にするとぬるっと動くようにしています。

そしてボタンの影になる部分はrepeating-linear-gradientを使いストライプにしています。

    background-image: repeating-linear-gradient(
      -45deg,
      #000,
      #000 1px,
      transparent 2px,
      transparent 5px
    );
/* ボタンのデザイン */
.button-border {
  position: absolute;
  top: 5vmin;
  left: 5vmin;
  padding: 0;
  background: none;
  border: none;
  transition: all 0.3s;
  
  span {
    position: relative;
    display: block;
    padding: 1rem;
    font-weight: 600;
    color: #000;
    background: #FFF;
    border: 2px solid #000;
    border-radius: 0.5rem;
  }

  &::before {
    position: absolute;
    bottom: -8px;
    left: 0;
    box-sizing: border-box;
    display: block;
    width: 100%;
    height: 14px;
    content: "";
    background: #FFF;
    background-image: repeating-linear-gradient(
      -45deg,
      #000,
      #000 1px,
      transparent 2px,
      transparent 5px
    );
    background-size: 7px 7px;
    border: 2px solid #000;
    border-radius: 0 0 0.5rem 0.5rem;
    transition: all 0.3s;
    backface-visibility: hidden;
  }
  
  &:hover {
    transform: translate(0, 3px);

    &::before {
      bottom: -5px;
    }
  }

  &:active {
    transform: translate(0, 7px);

    &::before {
      bottom: -1px;
    }
  }
}

スイッチロゴのスタイル指定

スイッチロゴを包括するブロックにスタイル指定をしていきます。

  • スイッチロゴが画面の上下・左右のど真ん中にくるように、top: 50%;left: 50%;を指定
  • スイッチロゴが表示される場所を指定した後に、transform: translate(-50%, -50%);を使って要素(今回の場合はスイッチロゴ)の大きさの半分を左上方向に戻して表示されるように指定します。
/* スイッチロゴを包括するブロックとNINTENDOのテキスト配置 */
#container {
  position: relative;
  top: 50%;
  left: 50%;
  float: left;
  transform: translate(-50%, -50%);

  > span {
    position: relative;
    left: 50%;
    float: left;
    margin-top: 7vmin;
    clear: both;
    font-size: 6.5vmin;
    color: #FFF;
    text-transform: uppercase;
    letter-spacing: 2vmin;
    transform: translateX(-50%);
  }
}

次にスイッチのコントローラーの動きを@keyframesを使って調整します。

vmin(ブラウザウィンドウの縦横サイズの小さい方の数値を基準にする)を使用して、デバイスの向きが変わっても小さい方の数値を反映させて動きに差異が出ないようにしています。
(縦500px、横1000pxの場合、vminは縦500pxを基準にします。)

/* スイッチコントローラーの上から落ちてくる動き */
@keyframes slidemotion {
  0% {
    margin-top: -15vmin;
  }
  30% {
    margin-top: -17vmin; 
  }
  100% {
    margin-top: 0;
  }
}

あとはスイッチロゴをCSSでゴリゴリと書いていきます。

&::before(疑似要素)を使って、コントローラーのスティック部分を作成しています。

/* スイッチロゴ */
#logo {
  position: relative;
  float: left;
  width: 55vmin;
  height: 55vmin;
  clear: both;

  #left, #right {
    position: relative;
    width: 47.5%;
    height: 100%;
    border: 4vmin solid #FFF;

    &::before {
      position: absolute;
      left: 50%;
      display: block;
      width: 60%;
      height: 0;
      padding-bottom: 60%;
      margin-left: -30%;
      content: '';
      border-radius: 50%;
    }
  }
  
  #left {
    float: left;
    border-top-left-radius: 17vmin;
    border-bottom-left-radius: 17vmin;

    &::before {
      top: 7vmin;
      background: #FFF;
    }
  }
  
  #right {
    float: right;
    margin-top: -15vmin;
    background: #FFF;
    border-top-right-radius: 17vmin;
    border-bottom-right-radius: 17vmin;
    animation: 0.3s slide-motion 1s linear forwards;

    &::before {
      bottom: 15vmin;
      background: #D20013;
    }
  }
}

JS解説

JSではボタンを押した時に以下の2つのイベントを発生させる処理を書いています。

  • スイッチロゴの表示/非表示を切り替える
  • スイッチロゴが表示されている時だけサウンドを流す
// ボタンON/OFFした時にスイッチロゴの表示切替え
const button = document.querySelector('button');
button.addEventListener('click', toggleDisplay);

function toggleDisplay() {
  const container = document.querySelector('#container');
  container.classList.toggle('hidden');
}

// ボタンONした時のみサウンドを流す
const audio = new Audio('https://kenyo--c.com/wp-content/themes/kenyoooc/codepen/audio/nintendo-switch-sound-effect.mp3');

const canPlayButton = document.getElementById('play-button');
let count = 1; //on/off用のカウンター変数
canPlayButton.addEventListener('click', showAudio);

function showAudio(e) {
  if (count === 1) {
    // audioを読み込み
    audio.load();
    // 1秒後にaudioを再生
    setTimeout(function () {
      play(audio);
    }, 1000);
    count = 0;
  } else {
    count = 1;
  };
};

function play(audio) {
  audio.play();
};

スイッチロゴの表示/非表示を切り替える

addEventListener() メソッドでボタンをクリックした時に呼び出される関数(toggleDisplay)を指定します。

そして、#containerブロックにclassListのメソッド、toggleを使ってCSSで用意していた.hiddenを付与してスイッチロゴの表示/非表示を切り替えます。

// ボタンON/OFFした時にスイッチロゴの表示切替え
const button = document.querySelector('button');
button.addEventListener('click', toggleDisplay);

function toggleDisplay() {
  const container = document.querySelector('#container');
  container.classList.toggle('hidden');
}

スイッチロゴが表示されている時だけサウンドを流す

サウンドは「Free Sounds Library」さんからダウンロードさせて頂きました。

サウンドの自動再生については、あらゆるブラウザーで自動的にオーディオが再生されないようになっているため、ユーザーがボタンをクリックした場合にのみ再生されるようにしています。

そのため、let count = 1;(カウンター変数)でボタンのon/offを判定しています。

// ボタンONした時のみサウンドを流す
const audio = new Audio('https://kenyo--c.com/wp-content/themes/kenyoooc/codepen/audio/nintendo-switch-sound-effect.mp3');

const canPlayButton = document.getElementById('play-button');
let count = 1; //on/off用のカウンター変数
canPlayButton.addEventListener('click', showAudio);

function showAudio(e) {
  if (count === 1) {
    // audioを読み込み
    audio.load();
    // 1秒後にaudioを再生
    setTimeout(function () {
      play(audio);
    }, 1000);
    count = 0;
  } else {
    count = 1;
  };
};

function play(audio) {
  audio.play();
};

※ユーザの承認を得て、audioの自動再生を可能にする方法についてはこちらの記事を参考にさせて頂きました。

ユーザの承認を得て、audioの自動再生を可能にする。chrome・safari対応【JavaScript】
audioを自動再生しようとすると発生するエラーこんな風にaudioタグの音声を自動再生しようとすると・・・。//html<audioid="audio"src="..."></au

まとめ

CSSとJSの勉強を兼ねて作ってみましたが、もうちょっとスマートに書ける方法がありましたらコメントにて教えて頂けますと嬉しいです!今後も時間があったらCSSでお絵描きシリーズをやっていきたいと思います…。時間があったら…。

comment

タイトルとURLをコピーしました