예전부터 즐겨보던 유튜브 채널인 Online Tutorial 에 흥미로운 영상이 올라왔다.
원본영상: https://www.youtube.com/watch?v=ShPPkZEeLPo&t=662s
Circular Navigation, 활성화 되면 원형으로 메뉴가 펼쳐지는 메뉴 네비게이션!
다른 프로젝트를 진행하며 막힘의 연속에 지쳐가고 있을 때 머리도 식힐겸 가볍게 만들어 볼 것이 생겨 신이 났던 것 같다.
사실 영상을 보며 따라서 코드만 배껴 쓰면 만들어지는 기능이지만 그렇게 하면 당연히 의미가 없으니
영상은 아이디어를 얻는 소스일 뿐! 시연 영상만 보고 처음부터 혼자 만들어 보려고 노력하였다.
사용 기술은 HTML, CSS, VanilaJS이다.
디자인 요소가 강조된 튜토리얼이다보니 JS는 active toggle을 위한 용도로 사용하였으며 추후에 draggable 기능을 추가할 때 주로 사용한 것을 제외하고는 CSS가 가장 주된 기술이라고 할 수 있겠다.
이 네비게이션의 독특한 점은 원형으로 퍼질 때 그냥 퍼지는 것이 아니라 나선형으로 퍼져서 개성있고 세련된 느낌을 준다.
// index.html
<body>
<div class="menu">
<div class="toggle nav">
<ion-icon name="add-outline"></ion-icon>
</div>
<li class="icon" style="--i: 0">
<ion-icon name="home-outline"></ion-icon>
</li>
<li class="icon" style="--i: 1">
<ion-icon name="aperture-outline"></ion-icon>
</li>
<li class="icon" style="--i: 2">
<ion-icon name="arrow-redo-outline"></ion-icon>
</li>
<li class="icon" style="--i: 3">
<ion-icon name="bookmark-outline"></ion-icon>
</li>
<li class="icon" style="--i: 4">
<ion-icon name="attach-outline"></ion-icon>
</li>
<li class="icon" style="--i: 5">
<ion-icon name="bluetooth-outline"></ion-icon>
</li>
<li class="icon" style="--i: 6">
<ion-icon name="call-outline"></ion-icon>
</li>
<li class="icon" style="--i: 7">
<ion-icon name="archive-outline"></ion-icon>
</li>
</div>
<script type="module" src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.js"></script>
<script src='index.js'></script>
</body>
원래 아이콘 사용을 위해서 Font awsome 를 애용했었다. Font awsome에는 무료 아이콘도 많으나 디테일한 차이점이 있는 모든 아이콘을 사용하기 위해서는 사용료를 지불해야 한다. 또한 회원가입 후 개인에게 주어지는 키트 키를 필수적으로 적용시켜야 해서 첫 사용자들에게는 부담스러운 면이 있었던 듯 하다.
Font Awsome 링크 https://fontawesome.com/
하지만 이번에 새로 알게된 사이트 ionicon은 사용방법도 매우 간단할 뿐 더러 사이트에서 제공하는 script만 html body 마지막에 적용시키면 무료로 바로 사용 가능하기 때문에 매우 편리하다 할 수 있겠다. 대신 상대적으로 Font Awsome에 비해 아이콘 수는 적다. 물론 자주 사용하는 대표적인 아이콘들은 거의 다 사용할 수 있기에 간단한 개인 프로젝트를 하기에는 전혀 문제가 없다.
ionicon 링크: https://ionic.io/ionicons
그리고 또 하나 얻은 꿀팁!
영상 첫부분을 보고 +아이콘과 x아이콘 두개를 삽입하려 했으나 +버튼을 rotate시켜서 x로 만드는 방법이 있었다.
하나의 아이콘을 사용하기 때문에 rotate만 적용시키면 번거롭게 아이콘의 display를 조정할 필요가 없다는 것!
매우 편리한 팁이라고 생각한다.
그렇게 해서 HTML은 금방 마무리 지을 수 있었다.
menu 클래스로 전체를 둘러 싸고 중심에 토글 역할을 할 nav toggle 클래스와 나머지 아이템들을 배치 시켰다.
style 에 변수를 입력한 이유는 변수에 따라 transition delay를 주어야 꽃처럼 차례대로 펼쳐지게 만들 수 있기 때문.
다음 과정은 가장 중요한 CSS.
// style.css
body {
box-sizing: border-box;
margin: 0;
background: rgb(238, 174, 202);
background: radial-gradient(
circle,
rgba(238, 174, 202, 1) 0%,
rgba(148, 187, 233, 1) 100%
);
width: 100%;
height: 100vh;
}
li {
list-style: none;
}
.menu {
display: flex;
justify-content: center;
align-items: center;
position: relative;
top: 50%;
left: 50%;
width: 250px;
height: 250px;
transform: translate(-50%, -50%);
transition: background-color 0.5s;
transition-delay: 0.3s;
border-radius: 50%;
}
.menu.active{
background-color: rgb(223, 145, 243);
}
ion-icon {
background-color: white;
width: 2rem;
height: 2rem;
padding: 0.5rem;
font-size: 1rem;
border-radius: 50%;
transition: background-color 250ms linear;
-webkit-box-shadow: 0px 0px 16px -3px #000000;
box-shadow: 0px 0px 16px -3px #000000;
}
.menu .toggle {
transition: transform 0.75s linear, background-color 250ms linear;
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.menu .toggle ion-icon {
width: 3.5rem;
height: 3.5rem;
}
.menu .toggle.active {
transform: rotate(315deg);
}
.menu .icon {
position: absolute;
transition: 0.75s ease-out;
transform-origin: 125px;
transform: rotate(0deg) translateX(125px) translateX(-50%);
left: 0;
transition-delay: calc(var(--i) * 0.1s);
}
.menu .icon.active {
transform: rotate(calc(var(--i) * 45deg));
}
.menu .icon ion-icon {
transition: 0.75s, background-color 200ms ease-in;
transition-delay: rotate calc(var(--i) * 0.1s);
}
.menu .icon.active ion-icon {
transform: rotate(calc(var(--i) * -45deg));
z-index: 1001;
}
.menu .toggle ion-icon:hover {
background-color: rgb(206, 89, 206);
}
.menu .icon.active ion-icon:hover {
background-color: rgb(206, 89, 206);
}
여기서 주의깊게 살펴봐야 할 태그는 3가지이다.
1. .toggle.active
위에서 말한 팁과 같이 +를 x로 바꾸는 부분.
rotate를 315로 해서 45로 했을 때보다 좀더 다이나믹하게 효과를 줄 수 있다.
몇바퀴 돌리는지에 따라 각도를 변경하면 됨
2. .icon
가장 애를 먹었던 부분.
이부분에서만 거의 30분을 까먹은 듯 하다.
다른부분은 어떻게 어떻게 끼워 맞췄는데 다음 부분은 답지를 확인할 수 밖에 없었다...
분명 시계방향으로 펼쳐져야하는데 아랫부분부터는 가장 짧은 동선으로 transform되는 모습.
이부분을 도대체 어떻게 해결해야 할까.... 한참을 고민하다가 영상을 통해 확인하였다.
rotate(0deg)를 부여해서 가장 짧은 동선이 아니라 0도부터 각 개체에 부여한 각도까지 늘어남으로서 시계방향으로 펼쳐지게 만들어야 한다.
3. .icon.active 와 ion-icon
HTML에서 설정한 변수 i를 통해 애니메이션을 핸들링하는 부분.
이렇게 변수를 설정해 놓으면 각 개체마다 transition-delay를 주거나 rotate시 독립적인 움직임을 부여할 수 있다.
마지막으로 JS는 간단하게 toggle정도만 적용해주면 마무리된다.
const toggle = document.querySelector('.toggle');
const icon = document.querySelectorAll('.icon')
toggle.onclick = e => {
toggle.classList.toggle('active');
icon.forEach(i => {
i.classList.toggle('active');
})
}
이렇게 해서 완성 된 네비게이션은.....!!
간단한 것이지만 역시 만들고 보니 뿌듯하다.
마치며...
소요시간은 약 2시간 정도 걸린 것 같다. 영상은 불과 13분정도인데 아직 이렇게 빠르게 만들기엔 나의 실력이 많이 부족함을 느낀다...
무엇이든 별거 아니게 보이는 기본적인 것들이 굉장히 중요하다. 이렇게 가끔 머리가 복잡할 때 간단하게 만들어 보는 것이 기본적인 기술 습득에 많은 도움이 되는 것 같다.
앞으로도 흥미있는 튜토리얼을 발견하거나 아이디어가 떠오르면 종종 글을 써보려한다.
'개발자일기 > Tutorial' 카테고리의 다른 글
빛번짐 효과, box-shadow & filter 활용하기 (feat. ionicons) (0) | 2022.02.03 |
---|---|
화면에 나타나면 애니메이션이 작동되게 하라!(CSS, VanilaJS) (2) | 2022.01.24 |
한 글자씩 나타나는 애니메이션(CSS, VanilaJS) (2) | 2022.01.13 |