icon-attention デザイン新しくしました。

icon-calendar 2019年4月10日

【Webデザイン】CSS3+SVGで便利なスマホ用円形メニューを作る

皆さんはスマホをどんな時に使いますか?
通勤中、寝る前、ご飯を食べながら、トイレの中でetc...

そんなときふとこう思ったことはありませんか?

「このサイト片手でこのメニュー開きにくいなー」

というわけで今回はスマホを持った時に自然に親指が
重なる位置に円形メニューを作ってみました。
以下にイメージ図載せておきます。

まずはデモと完成品

デモ

 

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>スマホを片手で操作</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="sm-menu">
      <menu class="sm-menu-list">
        <svg viewBox="0 0 150 150">
          
          <a href="#">
            <path d="M 22.06 145
                     A 90 90 50 0 1 15.43,69.22
                     L 71.81 89.74
                     A 30 30 50 0 0 74.02,115
                     Z" />
            <text transform="rotate(-5)" x="5" y="113">メニュー1</text>
          </a>
          <a href="#">
            <path d="M 15.43 69.22
                     A 90 90 50 0 1 69.22,15.43
                     L 89.74 71.81
                     A 30 30 50 0 0 71.81,89.74
                     Z" />
            <text transform="rotate(45)" x="55" y="3">メニュー2</text>
          </a>
          <a href="#">
            <path d="M 69.22 15.43
                     A 90 90 50 0 1 145,22.06
                     L 115 74.02
                     A 30 30 50 0 0 89.74,71.81
                     Z" />
            <text transform="rotate(95)" x="3" y="-105">メニュー3</text>
          </a>
        </svg>
      </menu>
      <div class="sm-menu-toggle">+</div>
      
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
      <script src="script.js"></script>
    </div>
  </body>
</html>

style.css

@keyframes sm-menu {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
* {
    margin: 0;
    padding: 0;
}
.sm-menu {
    width: 150px;
    height: 150px;
    position: fixed;
    bottom: 100px;
    right: 50px;
}
.sm-menu menu {
    width: 150px;
    height: 150px;
}
.sm-menu-list {
    display: none;
}
.sm-menu-list.active {
    display: block;
    animation: sm-menu 0.3s ease 0s;
}
.sm-menu-list svg {
    width: 150px;
    height: 150px;
}
.sm-menu-list a:nth-child(even) {
    fill: #000;
}
.sm-menu-list a:nth-child(odd) {
    fill: #555;
}
.sm-menu-list text {
    fill: #ccc;
    font-size: 70%;
}
.sm-menu-toggle {
    width: 50px;
    height: 50px;
    background-color: #000;
    border: 5px solid #555;
    border-radius: 50%;
    position: absolute;
    right: 25px;
    bottom: 25px;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #fff;
    font-weight: bold;
    font-size: 130%;
}

script.js

$(document).ready(function() {
    $(".sm-menu-toggle").on("click", function() {
        $(".sm-menu-list").toggleClass("active");
    });
});

SVGで扇形

<path d="M 22.06 145
         A 90 90 50 0 1 15.43,69.22
         L 71.81 89.74
         A 30 30 50 0 0 74.02,115
         Z" />

このコードでメニューそれぞれの扇形を形成しています。
接頭辞(MやAやLなど)+パラメータのような構造になっています。

接頭辞 意味
M x y 描画の初期位置
x,y: 座標
A xr yr c f1 f2 x,y 円弧の描画
xr,yr: それぞれ楕円の長辺短辺の半径(円であれば同値)
c: 円弧の角度
f1: 円周の短いほう(0に設定)、長いほう(1に設定)
f2: 反時計回りに描画(0に設定)、時計回りに描画(1に設定)
x,y: 円弧の終端位置の座標
L x y 線分の描画
x,y: 終端位置の座標
Z 初期位置と終端位置を結んで図形を閉じる