1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

第18回 JavaScript アニメーションによるサイドバー(translateX)

Posted at

はじめに

Webサイトによく出てくるサイドバーを作りたいと思います。

今回実施する内容

今回は、Webでよく出てくるサイドバーをanitematetranslateXを使用して作成したいと思います。
メニューアイコン(ハンバーガーアイコン)をクリックすると、画面左からサイドバーがスライドして表示され、再クリックするとサイドバーが左側へ消えていくものです。
scaleXを使用しようと思ったのですが、サイドバーはtranslateXの動作をしているようだなと思いました。
sidebar2-1.gif

ソースコード(Git Hub)

環境

OS: Windows 11 JP (64bit)
バージョン 125.0.2535.51 (公式ビルド) (64 ビット)

参考

用語

translateXの動作

まずは、画面内でサイドバーを動かす動作を試します。
以下の通り、メニューアイコン(ハンバーガーアイコン)をクリックすると、サイドバーが右、左、右などと交互に移動します。
サイドバーが移動中にクリックしても方向が変わります。
これを画面外から画面内へ移動するようにしてあげれば、サイドバーの出来上がりです。
sidebar.gif

ソースは以下の通り。

sideBar_translateX.html
sideBar_translateX.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sideBar</title>
    <link rel="stylesheet" href="sideBar_translateX.css" type="text/css">
    <script src="sideBar_translateX.js" defer></script>
</head>
<body>
    <div id="menuIcon">
        <span class="bar barTop"></span>
        <span class="bar barMiddle"></span>
        <span class="bar barBottom"></span>
    </div>
    <div id="sideBar">
        <div id="home">ホーム</div>
        <div id="mypage">マイページ</div>
        <div id="channel">チャンネル</div>
    </div>
</body>
</html>
sideBar_translateX.js
sideBar_translateX.js
let offset = -200;
/** side barの表示・非表示設定 */
document.getElementById("menuIcon").addEventListener("click", () => {
    showSideBar();
});

function showSideBar() {
    offset = -offset;
    const animation = document.getElementById("sideBar").animate(
        [
            {   transform: `translateX(${offset}px)`    }
        ],
        {
            duration: 500,
            fill: "forwards"
        },
    );
}
sideBar_translateX.css
sideBar_translateX.css
/* menu Icon用開始 */
#menuIcon {
  position: relative;
  top: 2px;
  left: 2px;
  width: 48px;
  height: 48px;
}

#menuIcon:hover {
  background-color: #999;
  border-radius: 50%;
}

.bar {
  position: absolute;
  left: 14px;
  width: 20px;
  height: 2px;
  background-color: #333;
}

.barTop {
  top: 14px;
}

.barMiddle {
  top: 23px;
}

.barBottom {
  top: 32px;
}
/* menu Icon用終了*/

/* side Bar用開始 */
#sideBar {
  position: absolute;
  bottom: 0px;
  left: 200px;
  width: 160px;
  height: calc(100vh - 70px);
  border: 2px solid gray;
}

sideBar_translatex.htmlの説明

まずはhtmlです。

html抜粋
<body>
    <div id="menuIcon">
        <span class="bar barTop"></span>
        <span class="bar barMiddle"></span>
        <span class="bar barBottom"></span>
    </div>
    <div id="sideBar">
        <div id="home">ホーム</div>
        <div id="mypage">マイページ</div>
        <div id="channel">チャンネル</div>
    </div>
</body>

div要素のid="menuIcon"は、メニューアイコンを作成する要素です。
メニューアイコンの作成は、以下で行っていますので、ここでは説明を割愛します。
第17回 JavaScript 「三」、「✕」みたいなメニューアイコン作成(CSSです)

div要素のid="sideBar"は、サイドバーを作成する要素です。 今回はサイドバーを作るのが目的なのでそれっぽい名前のdiv`要素を使っていますが、中身は今回の本質ではないため、適当です。

sideBar_translateX.jsの説明

javascriptの抜粋
let offset = -200;
/** side barの表示・非表示設定 */
document.getElementById("menuIcon").addEventListener("click", () => {
    showSideBar();
});

let offset = -200;は、サイドバーの左右の移動量を設定しています。今回は200px移動予定なので200としています。
そのあとは、メニューアイコンをクリックしたら、showSideBar()を実行するように、addEventListenerを追加しています。

javascriptの抜粋
function showSideBar() {
    offset = -offset;
    const animation = document.getElementById("sideBar").animate(
        [
            {   transform: `translateX(${offset}px)`    }
        ],
        {
            duration: 500,
            fill: "forwards"
        },
    );
}

showSideBarは中身はシンプルです。
offset = -offset;は、showSideBarが実行されるたびにサイドバーの左右の移動量をプラス方向とマイナス方向を入れ替えています。
その後のanimateを使用して、translateXでアニメーションさせています。
animateの使用方法は、第13回 JavaScript アニメーションによる拡大・縮小(animate版)で紹介していますので、詳細は割愛します。
translateXを実施して気づいたのですが、設定する値で、プラス方向やマイナス方向に移動するのですが、移動の基準は初期位置です。なので図の通りに移動することになります。

image.png

ついでに思ったのは、duration: 500に設定していますが、1回目も、2回目以降も500msで移動するため、1回目だけ移動距離が200pxで2回目以降は400px移動となるため、移動速度が少し違っているなと思いました。
500msだと気になるほどではないなと思いましたが。

sideBar_translateX.cssの説明

/* menu Icon用開始 */のところは、メニューアイコン用なので、割愛します。

cssの抜粋
/* side Bar用開始 */
#sideBar {
  position: absolute;
  bottom: 0px;
  left: 200px;
  width: 160px;
  height: calc(100vh - 70px);
  border: 2px solid gray;
}

中身はシンプルで、position: absolute;として、bottm: 0pxで画面下からの配置にしました。
left: 200px;は画面の真ん中くらいにするようにしたためで、実運用時はleft: -200pxとかになると思います。
サイドバーの幅は、width: 160px;としました。
サイドバーの高さは、height: calc(100vh -70px);としました。
これは、メニューアイコンが64pxで作成したため、その部分が被らないように少しマージンをいれて、100vhから70px短くした高さにしました。
borderは、今回は移動がわかるように枠をつけただけです。

サイドバーを作る

translateXの動作」をベースに、サイドバーの初期位置を画面外に持ってこれば完成です。

sideBar_translateX2.html
sideBar_translateX2.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sideBar</title>
    <link rel="stylesheet" href="sideBar_translateX2.css" type="text/css">
    <script src="sideBar_translateX2.js" defer></script>
</head>
<body>
    <div id="menuIcon">
        <span class="bar barTop"></span>
        <span class="bar barMiddle"></span>
        <span class="bar barBottom"></span>
    </div>
    <div id="sideBar">
        <div id="home">ホーム</div>
        <div id="mypage">マイページ</div>
        <div id="channel">チャンネル</div>
    </div>
</body>
</html>
sideBar_translateX2.js
sideBar_translateX2.js
let offset = -165;
/** side barの表示・非表示設定 */
document.getElementById("menuIcon").addEventListener("click", () => {
    showSideBar();
});

function showSideBar() {
    offset = -offset;
    const animation = document.getElementById("sideBar").animate(
        [
            {   transform: `translateX(${offset}px)`    }
        ],
        {
            duration: 100,
            fill: "forwards"
        },
    );
}
sideBar_translateX2.css
sideBar_translateX2.css
/* menu Icon用開始 */
#menuIcon {
  position: relative;
  top: 2px;
  left: 2px;
  width: 48px;
  height: 48px;
}

#menuIcon:hover {
  background-color: #999;
  border-radius: 50%;
}

.bar {
  position: absolute;
  left: 14px;
  width: 20px;
  height: 2px;
  background-color: #333;
}

.barTop {
  top: 14px;
}

.barMiddle {
  top: 23px;
}

.barBottom {
  top: 32px;
}
/* menu Icon用終了*/

/* side Bar用開始 */
#sideBar {
  position: absolute;
  bottom: 0px;
  left: -165px;
  width: 160px;
  height: calc(100vh - 70px);
  border: 2px solid gray;
}
JavaScriptの変数`offset`の値やCSS上の`left`の値だけ少し調整をしました。 Edgeでは問題なさそうでしたが、他のブラウザでどうなるかわかりません。その場合もう少しマージンを入れてもいいのかなとは思いました。 ちなみに、`width`と同じ160を`offset`や`left`に設定すると、少しサイドバーの枠が画面内に表示されてしまったため、多少のマージンは必要そうです。

おわりに

今回はサイドバーを作ってみました。
正直、思っていたよりも簡単に実現できて驚きました。
少しずつJavaScriptも慣れてきてソースコードも自然に書けるようになってきました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?