I have created a simple cube in CSS and would like to be able to rotate it around with click and drag to display text on the sides etc, but every time you click and drag, it resets to the original position. How could I store the last rotated angle to be able to ensure it starts where it left off? I appreciate any help. Here is the code:
// Select the Cube
const cube = document.querySelector(".cube");
const body = document.querySelector("body");
// Get the x, y position when click
window.addEventListener("mousedown", function(e) {
const x = e.clientX;
const y = e.clientY;
// rotate
window.addEventListener("mousemove", moveRotate);
function moveRotate(e) {
cube.style.transform = `
rotateX(${-(e.clientY - y) / 2}deg)
rotateY(${(e.clientX - x) / 2}deg)`;
body.style.cursor = "grabbing";
}
window.addEventListener("mouseup", function() {
window.removeEventListener("mousemove", moveRotate);
body.style.cursor = "context-menu";
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: rgb(0, 0, 0);
}
.cube {
position: absolute;
width: 300px;
height: 300px;
transform-style: preserve-3d;
}
.cube div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
}
.cube div span {
color: azure;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(black, rgb(0, 255, 0));
transform: rotateY(calc(90deg * var(--i))) translateZ(150px);
}
.top {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background: #222;
transform: rotateX(90deg) translateZ(150px);
}
.top div {
color: white;
position: absolute;
top: 45%;
left: 35%
}
.bottom {
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background: rgba(0, 255, 0);
transform: rotateX(90deg) translateZ(-150px);
}
<body>
<div >
<div ></div>
<div ></div>
<div >
<span class=front style="--i:0;">0</span>
<span class=left style="--i:1;">1</span>
<span class=back style="--i:2;">2</span>
<span class=right style="--i:3;">3</span>
</div>
</div>
</body>
CodePudding user response:
You need to store the last calculated rotation value on the mouseUp
event. Then add it to the value of the new calculated rotation in the mouseMove
listener. The initial value must be set to zero outside both events.
// Select the Cube
const cube = document.querySelector(".cube");
const body = document.querySelector("body");
let last_x = 0,
last_y = 0
// Get the x, y position when click
window.addEventListener("mousedown", function (e)
{
const x = e.clientX;
const y = e.clientY;
let new_x = 0,
new_y = 0;
// rotate
window.addEventListener("mousemove", moveRotate);
function moveRotate(e)
{
new_x = ((e.clientX - x) / 2) last_x
new_y = (-(e.clientY - y) / 2) last_y
cube.style.transform =`
rotateX(${new_y}deg)
rotateY(${new_x}deg)`;
body.style.cursor = "grabbing";
}
window.addEventListener("mouseup",function ()
{
last_x = new_x
last_y = new_y
window.removeEventListener("mousemove", moveRotate);
body.style.cursor = "context-menu";
});
});
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body
{
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: rgb(0, 0, 0);
}
.cube
{
position: absolute;
width: 300px;
height: 300px;
transform-style: preserve-3d;
}
.cube div
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
}
.cube div span
{
color:azure;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(black, rgb(0, 255, 0));
transform: rotateY(calc(90deg * var(--i))) translateZ(150px);
}
.top
{
position: absolute;
top:0;
left: 0;
width: 300px;
height: 300px;
background: #222;
transform: rotateX(90deg) translateZ(150px);
}
.top div
{
color: white;
position: absolute;
top: 45%;
left: 35%
}
.bottom
{
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background:rgba(0, 255,0);
transform: rotateX(90deg) translateZ(-150px);
}
<div >
<div ></div>
<div ></div>
<div >
<span class=front style="--i:0;">0</span>
<span class=left style="--i:1;">1</span>
<span class=back style="--i:2;">2</span>
<span class=right style="--i:3;">3</span>
</div>
</div>