Is the 3D cube spinning with a slight perspective glitch?

I've successfully created a spinning cube using html and css.

However, I'm facing an issue where pressing the up and down arrow keys causes the cube to rotate in a larger space rather than around its center. I've attempted using margin: 0 auto, but it only centers the cube on the webpage.

$(document).ready(function(){
    var yAngle = 0;
    var xAngle = 0;
    document.onkeydown = checkKey;

    function checkKey(e) {

        e = e || window.event;

        if (e.keyCode == '39') {
            yAngle = yAngle+5;
            $("section").css("transform",'rotateY('+yAngle+'deg)');
        }
        if (e.keyCode == '37'){
            yAngle = yAngle-5;
            $("section").css("transform",'rotateY('+yAngle+'deg)');
        }
        if (e.keyCode == '38'){
            xAngle = xAngle+5;
            $("section").css("transform","rotateX("+xAngle+"deg)");
        }
        if (e.keyCode == '40'){
            xAngle = xAngle-5;
            $("section").css("transform",'rotateX('+xAngle+'deg)');
        }
    }

    $("#button_left").click(function(){
        yAngle = yAngle-1;
        $("section").css("transform",'rotateY('+yAngle+'deg)');
    });
   
    $("#button_right").click(function(){
        yAngle = yAngle+1;
        $("section").css("transform","rotateY("+yAngle+"deg)");
    });
    $("#button_down").click(function(){
        xAngle = xAngle-1;
        $("section").css("transform",'rotateX('+xAngle+'deg)');
    });
    $("#button_up").click(function(){
        xAngle = xAngle+1;
        $("section").css("transform","rotateX("+xAngle+"deg)");
    });
});
.buttons {
    align: center;
}
.wrap {
        perspective: 800px;
        perspective-origin: 50% 100px;
}
.cube {
    margin: 0 auto;
        position: relative;
        width: 200px;
        transform-style: preserve-3d;
}
.cube div {
        box-shadow: inset 0 0 20px rgba(125,125,125,0.9);
        position: absolute;
        width: 200px;
        height: 200px;
}
.back {
    background: rgba(40,40,40,0.8);
        transform: translateZ(-100px) rotateY(180deg);
}
.right {
    background: rgba(189,25,400,0.3);
        transform: rotateY(-270deg) translateX(100px);
        transform-origin: top right;
}
.left {
    background: rgba(189,25,400,0.3);
        transform: rotateY(270deg) translateX(-100px);
        transform-origin: center left;
}
.top {
    background: rgba(189,25,400,0.3);
        transform: rotateX(-90deg) translateY(-100px);
        transform-origin: top center;
}
.bottom {
    background: rgba(189,25,400,0.3);
        transform: rotateX(90deg) translateY(100px);
        transform-origin: bottom center;
}
.front {
    background: rgba(189,25,400,0.3);
        transform: translateZ(100px);
}
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<body><br><br><br><br><br><br>
<div align="center" class="buttons">
<input type="button" value="<--" id="button_left">
<input type="button" value="-->" id="button_right">
<input type="button" value="down" id="button_down">
<input type="button" value="up" id="button_up">
</div>
<br><br><br><br><br><br>
<div class="wrap">
        <section class="cube">
                <div class="front"></div>
                <div class="back"></div>
                <div class="top"></div>
                <div class="bottom"></div>
                <div class="left"></div>
                <div class="right"></div>
        </section>
</div>

Answer №1

Your container .cube lacks a defined height, causing it to not expand when its child div elements have position:absolute;. As a result, its size remains fixed at 200px x 0px, leading to rotation around the center at coordinates (100px, 0px).

The solution is to assign a height to .cube, ensuring rotation at the center (100px, 100px)

.cube {
    margin: 0 auto;
    position: relative;
    width: 200px;
    height: 200px;
    transform-style: preserve-3d;
    transform-origin: center center;
}

$(document).ready(function(){
    var yAngle = 0;
    var xAngle = 0;
        document.onkeydown = checkKey;
        function checkKey(e) {
 
    e = e || window.event;
 
    if (e.keyCode == '39') {
        yAngle = yAngle+5;
        $("section").css("transform",'rotateY('+yAngle+'deg)');
    }
        if (e.keyCode == '37'){
            yAngle = yAngle-5;
        $("section").css("transform",'rotateY('+yAngle+'deg)');
        }
        if (e.keyCode == '38'){
            xAngle = xAngle+5;
        $("section").css("transform","rotateX("+xAngle+"deg)");
        }
        if (e.keyCode == '40'){
            xAngle = xAngle-5;
        $("section").css("transform",'rotateX('+xAngle+'deg)');
        }
        }
    $("#button_left").click(function(){
        yAngle = yAngle-1;
        $("section").css("transform",'rotateY('+yAngle+'deg)');
    });
   
    $("#button_right").click(function(){
        yAngle = yAngle+1;
        $("section").css("transform","rotateY("+yAngle+"deg)");
    });
        $("#button_down").click(function(){
        xAngle = xAngle-1;
        $("section").css("transform",'rotateX('+xAngle+'deg)');
    });
   
    $("#button_up").click(function(){
        xAngle = xAngle+1;
        $("section").css("transform","rotateX("+xAngle+"deg)");
    });
});
.buttons {
    align: center;
}
.wrap {
        perspective: 800px;
        perspective-origin: 50% 100px;
}
.cube {
    margin: 0 auto;
        position: relative;
        width: 200px;
        height: 200px;
        transform-style: preserve-3d;
        transform-origin: center center;
}
.cube div {
        box-shadow: inset 0 0 20px rgba(125,125,125,0.9);
        position: absolute;
        width: 200px;
        height: 200px;
}
.back {
    background: rgba(40,40,40,0.8);
        transform: translateZ(-100px) rotateY(180deg);
}
.right {
    background: rgba(189,25,400,0.3);
        transform: rotateY(-270deg) translateX(100px);
        transform-origin: top right;
}
.left {
    background: rgba(189,25,400,0.3);
        transform: rotateY(270deg) translateX(-100px);
        transform-origin: center left;
}
.top {
    background: rgba(189,25,400,0.3);
        transform: rotateX(-90deg) translateY(-100px);
        transform-origin: top center;
}
.bottom {
    background: rgba(189,25,400,0.3);
        transform: rotateX(90deg) translateY(100px);
        transform-origin: bottom center;
}
.front {
    background: rgba(189,25,400,0.3);
        transform: translateZ(100px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<body><br><br><br><br><br><br>
<div align="center" class="buttons">
<input type="button" value="<--" id="button_left">
<input type="button" value="-->" id="button_right">
<input type="button" value="down" id="button_down">
<input type="button" value="up" id="button_up">
</div>
<br><br><br><br><br><br>
<div class="wrap">
        <section class="cube">
                <div class="front"></div>
                <div class="back"></div>
                <div class="top"></div>
                <div class="bottom"></div>
                <div class="left"></div>
                <div class="right"></div>
        </section>
</div>

Answer №2

To ensure consistency, attempt to set all the transformations to the same value. For example, in one section you are using xAngle+/-5 and in another section you are using xAngle+/-1. It appears that there may be a confusion between the event names for the y axis and the key codes for the x axis. Since a step of 5 is being applied, you may notice a greater increase/decrease in values.

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

Distance between cursor and the conclusion of the text (autofocus)

I discovered a method to automatically position the cursor at the end of a string using autofocus: <input name="adtitle" type="text" id="adtitle" value="Some value" autofocus="" onfocus="this.setSelectionRange(this.value.length,this.value.length);"> ...

Adjust the width to ensure the height is within the bounds of the window screen?

I am currently in the process of developing a responsive website, and my goal is to have the homepage display without any need for scrolling. The layout consists of a 239px tall header, a footer that is 94px tall, and an Owl Carousel that slides through im ...

Increase the margin for the following item if it has a specific class using CSS

Here is the HTML code that I currently have: <div class="post"> <h2 class="title">TITLE: Kausalya</h2> <p class="content">CONTENT: Shaunaka Shakha</p> </div> <div class="post"> <h2 class="title"> ...

Is there a way to automatically submit an upload form once a file has been selected?

Need help with automatically submitting a file upload form when a file is selected. Is there a way to bypass the need for the user to click the Submit button? ...

Retrieve jQuery CSS styles from a JSON database

I've been attempting to pass CSS attributes into a jQuery method using data stored in a JSON database. However, it doesn't seem to be functioning as expected. I suspect that directly inputting the path to the JSON variable may not be the correct ...

Ways to activate the date input field and reformat it for smooth insertion or selection in mysqli

I would like to enable the input of dates in UK format - DD/MM/YYYY on an HTML form. Before any PHP code is executed, such as queries (e.g. select, insert, etc.), I want PHP to convert the entered date from DD/MM/YYYY to YYYY-MM-DD. HTML <div class="f ...

Having trouble incorporating custom elements with the document.execCommand function

I have been attempting to insert a custom element into an editable div using the document.execCommand method as described in detail on https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand. However, when I try to add a custom polymer eleme ...

I want to display a div above an image when hovering over it

.vpbutton {padding:4px;background-color:#EFEFEF;} .userbox img{padding:8px;background-color:#EFEFEF;} .userbox img:hover{opacity:.2;} <div class="userbox"> <img src='img.png' style='height:120px;width:120px;border:1p ...

Incorporate FontAwesome icons into table headers within an Angular framework

I am attempting to customize the icons for sorting in my table headers by following the guidelines laid out in the ng-bootstrap table tutorial. The NgbdSortableHeader directive plays a key role in changing the sorting of columns: @Directive({ selector: ...

How can I use jQuery to set the color of every other row in a

I'm facing an issue where I want to use jQuery to set the color of alternate rows in an HTML table. However, every time I add a new row, the color of the entire table switches. Below is the JavaScript code snippet that I am utilizing: var alternate = ...

Preserve the location of a moveable div using jQuery

I have implemented draggable divs in my JSP page, allowing users to move them around freely. After dragging the divs, I would like to save their positions either in a cookie or database for future reference. Could you please advise on the best way to ach ...

Arrange data into columns on a website

In my project, I'm exploring the challenge of creating a square 2 x 2 grid alongside a rectangular column on the right-hand side. While attempting to implement a grid system for the 2 x 2 layout, I encountered issues with the alignment of the rectang ...

CSS styling is not being applied to buttons within Ionic 2

I'm completely new to Ionic and hybrid apps as a whole. I've been experimenting with a test app, but for some reason, none of the CSS seems to be working. Could someone please help me figure out what mistake I might have made? Here are my files: ...

Showcasing Information Using AngularJS from a Json Array

My goal is to present data from a JSON array in a table using the code below. However, all the data is currently being shown in one row instead of each record appearing on separate rows with alternating colors - grey for even rows and white for odd rows. I ...

Opening the Gmail app from a link using JavaScript

What is the best way to open the Gmail app from a hyperlink? This link opens WhatsApp <a href="https://wa.me/">whatsapp</a> <a href="mailto:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6a1f190f ...

Ways to incorporate ng-app into an HTML element when HTML access is limited

In my current project, I am using Angular.js within a template system. The challenge I am facing is that I need to add ng-app to the html element, but I do not have direct access to do this on the page itself. Initially, my page structure looks like this: ...

Angular click event to compute a function and display the result on a separate page

Currently, I am developing a BMI app using Ionic Angular (latest version). The objective is to create a button that collects input data from fields and triggers a method to validate the inputs. Once validated, the app should display the results page with t ...

Angular Appreciation Meter

Looking to create a rating system using Angular. The square should turn green if there are more likes than dislikes, and red vice versa (check out the stackblitz link for reference). Check it out here: View demo I've tried debugging my code with con ...

Adjust the position of the element by lifting it slightly

I am looking to adjust the positioning of the number "01 / 04" to match the layout shown in this image: Here is what I have accomplished so far: This is how the code structure looks like in vue js at the moment: <img id="theZoomImage" sizes="100vw" : ...

What is the best way to add a value to the value attribute of a div using JavaScript?

Is there a way to insert a value into the value attribute of a div using Internet Explorer 9? I have attempted various JavaScript functions, but so far I can only modify the content inside the div and not the value attribute itself. <div id="mydiv" val ...