Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

115
Views
object rotation resets on new click with javascript

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 class="cube">
    <div class="top"></div>
    <div class="bottom"></div>
    <div class="sides">
      <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>

almost 4 years ago · Santiago Trujillo
1 answers
Answer question

0

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 class="cube">
      <div class="top"></div>
      <div class="bottom"></div>
      <div class="sides">
        <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>

almost 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!