<body>
<div class="cube">
<div class="face front"></div>
<div class="face back"></div>
<div class="face top"></div>
<div class="face bottom"></div>
<div class="face left"></div>
<div class="face right"></div>
</div>
</body>
$size: 50vmin;
@mixin face($color: white, $tx: 0px, $ty: 0px, $tz: 0px, $rx: 0deg, $ry: 0deg) {
background-color: $color;
transform: translateX($tx) translateY($ty) translateZ($tz) rotateX($rx)
rotateY($ry);
}
* {
margin: 0;
padding: 0;
}
body {
background-color: black;
height: 100vh;
overflow: hidden;
perspective: 1000px;
}
.cube {
transform: rotateX(-25deg) rotateY(25deg);
cursor: move;
transform-style: preserve-3d;
position: absolute;
width: $size;
height: $size;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
.face {
box-sizing: border-box;
border: 5px solid black;
width: $size;
height: $size;
position: absolute;
top: 0;
left: 0;
&.front {
@include face($tz: $size / 2);
}
&.back {
@include face($tz: -$size / 2);
}
&.top {
@include face($ty: -$size / 2, $rx: 90deg);
}
&.bottom {
@include face($ty: $size / 2, $rx: 90deg);
}
&.left {
@include face($tx: -$size / 2, $ry: 90deg);
}
&.right {
@include face($tx: $size / 2, $ry: 90deg);
}
}
}
View Compiled
const cubeEl = document.querySelector(".cube");
let clickX = 0;
let clickY = 0;
let moveX = 0;
let moveY = 0;
let lastX = -25;
let lastY = 25;
///////////////////
// 마우스 클릭 이벤트 //
///////////////////
cubeEl.addEventListener("mousedown", (e) => {
let isClick = true;
clickX = e.screenX;
clickY = e.screenY;
window.addEventListener("mousemove", (e) => {
if (isClick) {
const nowX = e.screenX;
const nowY = e.screenY;
moveX = lastX + clickY - nowY;
moveY = lastY - clickX + nowX;
console.log(`X 회전각 : ${moveX}
Y 회전각 : ${moveY}`);
gsap.to(cubeEl, 0, {
transform: `rotateX(${moveX}deg) rotateY(${moveY}deg)`,
});
}
});
window.addEventListener(
"mouseup",
(e) => {
if (isClick) {
lastX = moveX;
lastY = moveY;
isClick = false;
}
},
{ once: true }
);
});
///////////////////
// 터치 이벤트 //
///////////////////
cubeEl.addEventListener(
"touchstart",
(e) => {
let isTouch = true;
clickX = e.targetTouches[0].screenX;
clickY = e.targetTouches[0].screenY;
window.addEventListener("touchmove", (e) => {
if (isTouch) {
const nowX = e.targetTouches[0].screenX;
const nowY = e.targetTouches[0].screenY;
moveX = lastX + clickY - nowY;
moveY = lastY - clickX + nowX;
console.log(`X 회전각 : ${moveX}
Y 회전각 : ${moveY}`);
gsap.to(cubeEl, 0, {
transform: `rotateX(${moveX}deg) rotateY(${moveY}deg)`,
});
}
});
window.addEventListener(
"touchend",
(e) => {
if (isTouch) {
lastX = moveX;
lastY = moveY;
isTouch = false;
}
},
{ once: true }
);
},
false
);
This Pen doesn't use any external CSS resources.