Adjust CSS transformations independent of the element's position

const 
        doc = document,
        qS = `querySelector`,
        qSA = `querySelectorAll`,
        root = doc[ qS ]( `html` ),
        cubeContainer = doc[ qS ]( `.cube-container` ),
        cubeWrap = doc[ qS ]( `.cube-wrap` ),
        cube = doc[ qS ]( `.cube` ),
        aside = doc[ qS ]( `aside` );
    
      function clicked( event ) {
        const element = event.target;
    
        if( element.classList == `x-rotate` ) {
          cubeContainer.style.transform += 
            `rotateY( 45deg )`;
        }
        if( element.classList == `y-rotate` ) {
          cubeWrap.style.transform += 
            `rotateX( -45deg )`;
        }
        if( element.classList == `z-rotate` ) {
          cube.style.transform += 
            `rotateZ( 45deg )`;
        }
      }
    
      aside.addEventListener( `click`, clicked );
body, section, aside, div {
        display: flex;
        justify-content: center;
        align-items: center;
      }
      ::selection {
        background-color: var( --dim );
      }
      :root {
        --length: 10rem;
        --dim: rgba( 0,0,0,0.125 );
      }
      * {
        box-sizing: border-box;
        transform-style: preserve-3d;
        margin: 0;
        padding: 0;
      }
      html, body {
        overflow: hidden;
        height: 100%;
      }
      html {
        font-size: 0.9rem;
      }
      body {
        perspective: 15rem;
        font-family: Arial;
      }
      .scene-wrap {
        transform: translateZ( -7.5rem );
      }
      /* More CSS styles here */
      
<!-- \\\ \\ \\ SCENE CONTAINER // // /// -->
      <section class='scene-container'>
        <!-- \\ \\\ \\\ SCENE WRAP /// /// // -->
        <section class='scene-wrap'>
          <!-- \\\ \\\ \\\ SCENE /// /// /// -->
          <section class='scene'>
            <!-- \ \ \ CUBE CONTAINER / / / -->
            <div class='cube-container'>
              <!-- \ \ \ CUBE WRAP / / / -->
              <div class='cube-wrap'>
                <!-- \ \ \ CUBE / / / -->
                <div class='cube'>
                  <!-- \ front-back / -->
                  <div class='front-back'>
                    <!-- More HTML code here -->
                  </div>
                </div>
            </div>
            </section>
          </section>
        </section>
    </section>
    <!-- /// // // SCENE CONTAINER \\ \\ \\\ -->

    <!-- \\\ \\\ \\\ ASIDE /// /// /// -->
    <aside>
      <svg class='x-rotate'>
        <path 
          class='x-rotate'
          d=
            '
              M 42,75
              C 50,70,58,63,65,59
              C 58,53,50,48,42,43
              V 53
              C -25,44,56,28,82,41
              C 91,46,78,50,72,51
              V 62
              C 114,51,100,28,59,26
              C 18,24,-14,41,10,56
              C 21,62,30,62,42,64
              Z
            '            
        />
      </svg>

      <!-- More SVG code for controls -->

    </aside>
    <!-- /// /// /// ASIDE \\\ \\\ \\\ -->

The provided snippet applies rotations to a cube relative to its current position. However, the goal is to rotate the cube globally with respect to the document's "view". Each click on a rotation control button should reset and apply new rotations without considering previous transforms.

How can the rotations be reset or frozen after each button click to ensure subsequent rotations are not influenced by prior ones?

Answer №1

Check this out for a slightly improved experience, although there may be slight snapping when changing rotations - not entirely sure if that meets your needs:

const 
  doc = document,
  qS = `querySelector`,
  qSA = `querySelectorAll`,
  root = doc[ qS ]( `html` ),
  cubeContainer = doc[ qS ]( `.cube-container` ),
  cubeWrap = doc[ qS ]( `.cube-wrap` ),
  cube = doc[ qS ]( `.cube` ),
  aside = doc[ qS ]( `aside` );

let rotplane = 1,
    roty = 0,
    rotx = 0,
    rotz = 0;

function clearTransform(){

  cubeWrap.style.transitionDuration="0s";
  cube.style.transitionDuration="0s";
  cubeContainer.style.transitionDuration="0s";

  cubeWrap.style.transform="initial";
  cubeContainer.style.transform="initial";
  cube.style.transform="initial"; 
}

function clicked( event ) {
  const element = event.target;

  if( element.classList == `x-rotate` ) {
    if(rotplane != 1){
        clearTransform();
        rotplane = 1;
        roty = 0;
    }

    roty += 45;
    cubeContainer.style.transform = `rotateY( ${roty}deg )`;
    cubeContainer.style.transitionDuration="1s";

  } else if( element.classList == `y-rotate` ) {
    if(rotplane != 2){
        clearTransform();
        rotplane = 2;
        rotx = 0;
    }

    rotx -= 45;
    cubeWrap.style.transform = `rotateX( ${rotx}deg )`;
    cubeWrap.style.transitionDuration="1s";

  }else if( element.classList == `z-rotate` ) {    
       if(rotplane != 3){
        clearTransform();
        rotplane = 3;
        rotz = 0;
       }

    rotz += 45
    cube.style.transform = `rotateZ( ${rotz}deg )`;
    cube.style.transitionDuration="1s";

  }
}

aside.addEventListener( `click`, clicked );

Answer №2

Discovered a workaround to get this functionality working by always enclosing the cube in a parent element when a control is activated and applying transforms to that parent container. As pointed out by @Creon Noir, this method is not ideal because it keeps generating parent elements and applying transforms to them. This could lead to a large number of elements in the DOM if a user clicks many times.

Despite its shortcomings, this is the only solution I found to address my original issue.

const 
  doc = document,
  qS = `querySelector`,
  scene = doc[ qS ]( `.scene` ),
  aside = doc[ qS ]( `aside` );

function clicked( event ) {
  const element = event.target;

  if( element.classList == `x-rotate` ) {
    scene.innerHTML = `<section>${ scene.innerHTML }</section>`;
    setTimeout(
      function() {
        scene.children[ 0 ].style.transform += `rotateY( 45deg )`;
      }, 
      1
    )
  }
  if( element.classList == `y-rotate` ) {
    scene.innerHTML = `<section>${ scene.innerHTML }</section>`;
    setTimeout(
      function() {
        scene.children[ 0 ].style.transform += `rotateX( -45deg )`;
      }, 
      1
    )
  }
  if( element.classList == `z-rotate` ) {
    scene.innerHTML = `<section>${ scene.innerHTML }</section>`;
    setTimeout(
      function() {
        scene.children[ 0 ].style.transform += `rotateZ( 45deg )`;
      }, 
      1
    )
  }
}

aside.addEventListener( `click`, clicked );

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Slide in the Toggle Effect to Your Navigation Menu

Seeking help with enhancing my jQuery dropdown menu to include a slide down toggle effect similar to this example: http://jsfiddle.net/LaSsr/188/. Any assistance in applying this slide effect to the following JSfiddle would be greatly appreciated. Thank yo ...

Tips for replacing the new line character within a string to allow the <p> tag to display the new line

My current project involves a React application with a specific condition: When a string contains a new line character, the <p>{string}</p> tag that displays the string should be replaced with an HTML new line character. However, simply repl ...

Modifying the background color and linking it to a different class in Android Studio: A step-by-step guide

Recently, I developed a settings feature for my project that allows users to change the background color. However, I noticed that when I return to the home page, the settings are not saving or syncing properly. Any suggestions on how I can sync this info ...

Tips for automating the save button click in a form with jQuery

Is it possible to have a form with a dropdown menu that automatically saves when the user selects an option, without requiring them to click a separate "save" button? I want the action to take place as soon as the dropdown value is changed. Here is a demo: ...

"Transferring a collection to a new collection in mongoDB: A step-by-step

Can you assist me with transferring one collection to another collection in a separate database? I am able to read the data from the first collection successfully. ...

Guide to implementing the patchValues() method in conjunction with the <mat-form-field> within the (keyup.enter) event binding

I am currently working on a feature that populates the city based on a zip code input. I have successfully achieved this functionality using normal HTML tags with the (keyup) event binding. However, when trying to implement it using CSS, I had to use (keyu ...

What is the method for adding an attribute without a value to an HtmlGenericControl in C#

In my C#/ASP.net project, I am creating a new HtmlGenericControl and I need to add an attribute to the control without assigning it a value. This means having no ="" after the attribute name. oHtmlGenericControl = new HtmlGenericControl("MyHtmlTag"); oHtm ...

What is the enigmatic void hovering beyond the bounds of the HTML layout?

I am facing an issue with a div container that contains four spans. <body> <main> <div> <span>One</span> <span>Two</span> <span>Three</span> <span>Four</span> ...

What is the best way to determine if an Express.js session is currently active?

I was looking for a way to verify the status of an active session in my Express.js application, but I couldn't find any relevant information. My sessions are stored in a MongoDB store using connect-mongo. The purpose of this is to determine if a user& ...

Any idea why the HTML Select dropdown isn't functioning properly in Angular 2?

I am facing an issue with an Angular 2 Form. I am trying to include an html select but it is not working. I have checked the Angular 2 Documentation and even the live examples provided, like the HERO FORM, are not working. You can view the Hero Form Live E ...

viewing the Jenkins HTML report

I am currently working on a Jenkins job that utilizes the HTML publisher plugin to run selenium automation tests and produces a link to a HTML test result report on the Jenkins job details page. I am seeking a way to share this HTML report link with stak ...

The expected behavior is not displayed when using Async.waterfall within a promise queue

In our software implementation, we have utilized a promise queue feature using the q library. The sequence of functions is structured as follows: PQFn1 -(then)- PQFn2 - .... Within PQFn1, an array of values is passed to a callback function implemented wi ...

IE7 disregards the margin set in a div after a div that has been positioned absolutely

Within a container, I have two divs - the first one with absolute positioning. Strangely, in IE7, the second div doesn't seem to acknowledge the top margin. Padding works fine, but for visual consistency, I prefer using margin. The culprit appears to ...

JkMegaMenu drop-down menus in Chrome are shifting to the left when the window is resized

Currently, I am utilizing the JKmegamenu plugin to incorporate a megamenu into a website that is currently under development. The megamenu functions properly and has an attractive appearance. However, there seems to be an issue where the drop-down divs shi ...

What is the method that Google uses to automatically load the footer at the bottom of the web page?

Google manages to keep its footer at the bottom of the browser regardless of resolution when fully maximized. How can I achieve a similar effect? ...

Implementing dynamic URLs using static routing in Express

I'm looking for a way to render a page statically in Express that involves using a dynamic URL. For example, In my forum, users create posts and each post has its unique URL that shows the post when clicked: localhost:8080/posts/postNumber Current ...

Saving user input as a variable and sending it to the server using ajax and javascript

Seeking a way to save 'gender' and 'age' input as variables and then submit them to the server using ajax. In my attempt, when checking the console output, the gender variable was successfully saved while the age variable did not work a ...

What is causing the error that app.js file cannot be located?

Here is the layout of my directory: ReactCourse // Main folder public // Subfolder within ReactCourse index.html // HTML file with linked js file app.js // JavaScript file This is the content of index.html: <!DOCTYPE ...

Struggling to create a web application using parcel-bundler (Java not loading post-compilation)

Hey everyone, I've been searching online for a solution to my problem with parcel while working on a bootstrap web project, but I haven't had any luck. So now, I'm reaching out to you all for help. Bear with me as I explain the situation in ...

Encasing the bootstrap dropdown menu and trigger within individual parent divs for a tidier appearance

Is it possible to toggle a bootstrap dropdown when it is wrapped in another div by using attributes such as data-target or aria-labelledby? I have seen examples where data-toggle="dropdown" and class="dropdown-menu" are siblings. An example of what I am r ...