[HTML, CSS, JS] 드래그로 회전 가능한 정육면체 만들기

소고기는레어·2022년 1월 5일
31

Project 🗂

목록 보기
14/15
post-thumbnail

https://codepen.io/RAREBEEF/pen/eYGKZKL

JS와 CSS를 사용하여 기존에 만들던 것과는 다른 무언가를 만들어보고 싶었다. 3d로 무언가를 구현해보면 좋겠다는 생각이 들었는데, 처음엔 구체를 만들어볼까 했으나 표면이 꽉 채워진 구체는 현실적으로 구현하기가 어려울 것 같아서 무난하고 전체적으로 균형잡힌 정육면체를 제작해보기 했다.

1. 정육면체 구현

정육면체의 구현은 HTML 그리고 CSS 만으로 가능하다.

HTML

축과 컨테이너 역할을 할 요소를 만들고 자식으로 정육면체의 각 면이 될 요소 6개를 생성한다.

CSS

축과 컨테이너 역할을 할 요소에 transform-style: preserve-3d; 를 부여하여 3d 공간에 위치시킨다.

자식으로 들어있는 각 면들은 하나씩 차근차근 translateX, translateY, translateZ, rotateX, rotateY 로 위치와 각도를 조절한다.

잘 사용하지 않는 translateZ 를 사용하게 되는데, 3차원 공간이라 z축까지 고려해야하기 때문이다.

  • SCSS
    SCSS를 활용하였다. 평소에도 모든 CSS를 SCSS로 작성하긴 하지만 이번 정육면체에서 SCSS의 도움을 많이 받았다.

    우선 각 면은 같은 선언이 반복적으로 등장하지만 값이 제각각이기 때문에 개별적으로 선언이 필요하다. @mixin 을 통해 이러한 부분의 코드를 재사용하였다. 평소에는 잘 사용하지 않던 기능이었는데, 이번 기회를 통해 제대로 활용해볼 수 있어서 좋았다.

    또한 변수 $size를 선언하고 사용하였다.
    이 변수는 각 면의 크기와 위치를 잡는 기준으로 사용하였다. 따라서 변수 값 하나만 변경하여 정육면체의 크기를 손쉽게 수정할 수 있다.

2. 드래그를 통한 회전기능 추가

정육면체의 회전은 JS로 구현하였다.

화려한 색 없이도 회전을 통해 정육면체를 둘러볼 수 있기 때문에 색상은 최대한 깔끔하게 만들었다.

처음에는 단순히 버튼을 통해 상하좌우로 한칸씩 회전하는 기능을 넣으려고 했으나 사용자에게 조금 더 자유도를 부여하기 위해 드래그를 통한 회전 기능으로 노선을 변경하였다.

JS

회전은 gsap을 통해 처리하였다.

좌표는 mousedown, mousemove 등의 이벤트에서 불러와서 사용하였다.

X축 회전각은 최초 클릭 Y좌표에서 드래그를 통해 이동한 마지막 Y좌표를 빼고
Y축 회전각은 최초 클릭 X좌표에서 드래그를 통해 이동한 마지막 X좌표를 더한 뒤
gsap을 통해 실시간으로 계산된 회전각을 적용시켜 주었다.

이렇게만 할 경우 매번 클릭시마다 정육면체가 최초 각도로 돌아간 뒤 다시 회전을 시작하는 문제가 있다. 따라서 마지막에 적용한 회전각을 저장하고 이를 기준으로 다시 회전각을 계산하는 방법을 사용했다.

터치 대응

같은 내용의 코드를 마우스 이벤트가 아닌 터치 이벤트로 변경하여 스마트폰 터치를 통한 회전도 가능하도록 하였다.

profile
https://www.rarebeef.co.kr/

3개의 댓글

comment-user-thumbnail
2022년 1월 6일

글 잘 읽었습니다 !

답글 달기
comment-user-thumbnail
2022년 1월 14일

저는 아직 평면 구현밖에 못하는데 멋지네요!

답글 달기

A-Frame 써보세요. 쉽고 짱쎔

답글 달기