サークル(円形)ナビゲーションメニューを作る

サークル(円形)ナビゲーションメニューを作る

※この記事は2016年6月10日に書かれたもので、内容が古い可能性がありますのでご注意ください。

Circular Fly-Out Navigation Menuの作り方

Circular Fly-Out Navigation MenuのBlogを参考にさせていただいてサークルをClick(Tap)すると「ぴょっこり」飛び出すサークルナビゲーションメニューを作ったので覚えがき。
Demo

circleMenu.min.jsを使ったサークルメニュー画像
Click(Tap)すると

circleMenu.min.jsを使ったサークルナビゲーションメニュー画像「Click(Tap)時」

メニューリスト(ul)でHTMLを追加します。

HTML

<div id="c-circle-nav" class="c-circle-nav">
      <button id="c-circle-nav__toggle" class="c-circle-nav__toggle">
        <span>Toggle</span>
      </button>
      <ul class="c-circle-nav__items">
        <li class="c-circle-nav__item">
          <a href="#" class="c-circle-nav__link">
            <center><img src="images/House.png"></center>
          </a>
        </li>
        <li class="c-circle-nav__item">
          <a href="#" class="c-circle-nav__link">
            <center><img src="images/Facebook.png"></center>
          </a>
        </li>
        <li class="c-circle-nav__item">
          <a href="#" class="c-circle-nav__link">
            <center><img src="images/Pinterest.png"></center>
          </a>
        </li>
        <li class="c-circle-nav__item">
          <a href="#" class="c-circle-nav__link">
            <center><img src="images/Twitter.png"></center>
          </a>
        </li>
        <li class="c-circle-nav__item">
          <a href="#" class="c-circle-nav__link">
            <center><img src="images/Google.png"></center>
          </a>
        </li>
      </ul>
    </div>

レスポンシブでも対応できるように下記のようなCSSを記述しました。

CSS

.c-circle-nav__toggle,
.c-circle-nav__toggle span {
transition: background 0.3s;
-webkit-transition: background 0.3s;
}
.c-circle-nav {
position: fixed;
bottom: 12px;
right: 12px;
z-index: 1000;
width: 48px;
height: 48px;
border-radius: 24px;
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav {
width: 96px;
height: 96px;
border-radius: 48px;
}
}
.c-circle-nav__items {
display: block;
list-style: none;
position: absolute;
z-index: 90;
margin: 0;
padding: 0;
}
.c-circle-nav__item {
display: block;
position: absolute;
top: 0;
left: 0;
width: 48px;
height: 48px;
border-radius: 24px;
opacity: 0;
-webkit-transition-property: -webkit-transform,opacity;
transition-property: transform,opacity;
-webkit-transition-duration: 0.3s,.3s;
transition-duration: 0.3s,.3s;
-webkit-transition-timing-function: cubic-bezier(.35,-.59,.47,.97);
transition-timing-function: cubic-bezier(.35,-.59,.47,.97);
}
.c-circle-nav__item:nth-child(1) {
-webkit-transition-delay: 0.4s;
transition-delay: 0.4s;
}
.c-circle-nav__item:nth-child(2) {
-webkit-transition-delay: 0.3s;
transition-delay: 0.3s;
}
.c-circle-nav__item:nth-child(3) {
-webkit-transition-delay: 0.2s;
transition-delay: 0.2s;
}
.c-circle-nav__item:nth-child(4) {
-webkit-transition-delay: 0.1s;
transition-delay: 0.1s;
}
.c-circle-nav__item:nth-child(5) {
-webkit-transition-delay: 0s;
transition-delay: 0s;
}
.c-circle-nav.is-active .c-circle-nav__item {
-webkit-transition-timing-function: cubic-bezier(.35,.03,.47,1.59);
transition-timing-function: cubic-bezier(.35,.03,.47,1.59);
opacity: 1;
}
.c-circle-nav.is-active .c-circle-nav__item:nth-child(1) {
-webkit-transition-delay: 0s;
transition-delay: 0s;
-webkit-transform: translate(-144px,0);
-ms-transform: translate(-144px,0);
transform: translate(-144px,0);
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav__item {
width: 96px;
height: 96px;
border-radius: 48px;
}
.c-circle-nav.is-active .c-circle-nav__item:nth-child(1) {
-webkit-transform: translate(-288px,0);
-ms-transform: translate(-288px,0);
transform: translate(-288px,0);
}
}
.c-circle-nav.is-active .c-circle-nav__item:nth-child(2) {
-webkit-transition-delay: 0.1s;
transition-delay: 0.1s;
-webkit-transform: translate(-134px,-56px);
-ms-transform: translate(-134px,-56px);
transform: translate(-134px,-56px);
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav.is-active .c-circle-nav__item:nth-child(2) {
-webkit-transform: translate(-267px,-111px);
-ms-transform: translate(-267px,-111px);
transform: translate(-267px,-111px);
}
}
.c-circle-nav.is-active .c-circle-nav__item:nth-child(3) {
-webkit-transition-delay: 0.2s;
transition-delay: 0.2s;
-webkit-transform: translate(-102px,-102px);
-ms-transform: translate(-102px,-102px);
transform: translate(-102px,-102px);
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav.is-active .c-circle-nav__item:nth-child(3) {
-webkit-transform: translate(-204px,-204px);
-ms-transform: translate(-204px,-204px);
transform: translate(-204px,-204px);
}
}
.c-circle-nav.is-active .c-circle-nav__item:nth-child(4) {
-webkit-transition-delay: 0.3s;
transition-delay: 0.3s;
-webkit-transform: translate(-56px,-134px);
-ms-transform: translate(-56px,-134px);
transform: translate(-56px,-134px);
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav.is-active .c-circle-nav__item:nth-child(4) {
-webkit-transform: translate(-111px,-267px);
-ms-transform: translate(-111px,-267px);
transform: translate(-111px,-267px);
}
}
.c-circle-nav.is-active .c-circle-nav__item:nth-child(5) {
-webkit-transition-delay: 0.4s;
transition-delay: 0.4s;
-webkit-transform: translate(0,-144px);
-ms-transform: translate(0,-144px);
transform: translate(0,-144px);
}
.c-circle-nav__link {
display: block;
width: 100%;
height: 100%;
border-radius: 24px;
box-shadow: inset 0 0 0 2px #fff;
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav.is-active .c-circle-nav__item:nth-child(5) {
-webkit-transform: translate(0,-288px);
-ms-transform: translate(0,-288px);
transform: translate(0,-288px);
}
.c-circle-nav__link {
border-radius: 48px;
}
}
.c-circle-nav__link img {
display: block;
max-width: 100%;
height: auto;
padding-top: 15px;
}
.c-circle-nav__link:hover {
box-shadow: inset 0 0 0 2px #e91e63;
}
.c-circle-nav__toggle {
display: block;
position: absolute;
z-index: 100;
margin: 0;
padding: 0;
width: 48px;
height: 48px;
background-color: #e91e63;
font: inherit;
font-size: 0;
text-indent: -9999px;
border-radius: 24px;
cursor: pointer;
border: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
box-shadow: none;
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav__toggle {
width: 96px;
height: 96px;
border-radius: 48px;
}
}
.c-circle-nav__toggle.is-active,
.c-circle-nav__toggle:focus,
.c-circle-nav__toggle:hover {
outline: 0;
background-color: #e91e63;
}
.c-circle-nav__toggle span,
.c-circle-nav__toggle span::after,
.c-circle-nav__toggle span::before {
display: block;
position: absolute;
height: 4px;
background: #fff;
border-radius: 1px;
}
.c-circle-nav__toggle span {
top: 22px;
left: 10px;
right: 10px;
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav__toggle span,
.c-circle-nav__toggle span::after,
.c-circle-nav__toggle span::before {
height: 8px;
border-radius: 2px;
}
.c-circle-nav__toggle span {
top: 44px;
left: 20px;
right: 20px;
}
}
.c-circle-nav__toggle span::after,
.c-circle-nav__toggle span::before {
left: 0;
width: 100%;
content: "";
-webkit-transition-duration: 0.3s,.3s;
transition-duration: 0.3s,.3s;
-webkit-transition-delay: 0.3s,0s;
transition-delay: 0.3s,0s;
}
.c-circle-nav__toggle span::before {
top: -8px;
-webkit-transition-property: top,-webkit-transform;
transition-property: top,transform;
}
.c-circle-nav__toggle span::after {
bottom: -8px;
-webkit-transition-property: bottom,-webkit-transform;
transition-property: bottom,transform;
}
@media (min-width:480px)and (min-height:480px) {
.c-circle-nav__toggle span::before {
top: -16px;
}
.c-circle-nav__toggle span::after {
bottom: -16px;
}
}
.c-circle-nav__toggle.is-active span {
background: 0 0;
}
.c-circle-nav__toggle.is-active span::before {
top: 0;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transition-delay: 0s,.3s;
transition-delay: 0s,.3s;
}
.c-circle-nav__toggle.is-active span::after {
bottom: 0;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transition-delay: 0s,.3s;
transition-delay: 0s,.3s;
}
.c-mask {
position: fixed;
top: 0;
left: 0;
z-index: 900;
visibility: hidden;
opacity: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.8);
-webkit-transition: opacity 0.3s,visibility 0.3s;
transition: opacity 0.3s,visibility 0.3s;
}
.c-mask.is-active {
opacity: 1;
visibility: visible;
}

js(jQuery)

「jquery.js」と外部ファイルとして「circleMenu.js」を記述します。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="js/circleMenu.js"></script>

「circleMenu.js」の内容は下記のようになっています。

!function () {
"use strict";
function c() {
s
.classList
.add(n),
t
.classList
.add(n),
i
.classList
.add(n)
}
function e() {
s
.classList
.remove(n),
t
.classList
.remove(n),
i
.classList
.remove(n)
}
var s = document.querySelector("#c-circle-nav"),
t = document.querySelector("#c-circle-nav__toggle"),
i = document.createElement("div"),
n = "is-active";
i
.classList
.add("c-mask"),
document
.body
.appendChild(i),
t.addEventListener("click", function (s) {
s.preventDefault(),
t
.classList
.contains(n)
? e()
: c()
}),
i.addEventListener("click", function () {
e(),
console.log("click")
})
}();

これで、レスポンシブで使えるサークルメニューができました。

以上、今日の覚えがき。