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

Tips for showcasing a table generated from various input types on a separate page after pressing the submit button

After creating two JavaScript functions, I am eager to utilize both of them upon pressing the submit button on my form. The first function is already integrated into the submit button and activates a paragraph display upon submission. Now, I intend to sh ...

The entire title serves as a hyperlink, not just the text portion

Apologies if I'm making mistakes, I'm just starting out with coding and navigating this website. So here's the deal: I am trying to add advertisements to my website on the left and right sides of the centered "Logo" at the top. The issue i ...

Tips for showcasing an image prior to uploading within a personalized design input file

I am facing an issue with displaying multiple images inside custom style input file labels before uploading them to the database. Currently, the script I am using only displays one image at a time and in random positions. My goal is to have each image ap ...

Ways to display and modify chosen and not chosen categories on the product editing page

I have three tables Categories: cat_id ... other ... primary key (cat_id) Product: Product_id ... other ... primary key (Product_id) Product_cat: Product_id foreign key (post.Product_id) cat_id foreign key (Categories.cat ...

Tips for dynamically resizing the content area using CSS without the need for javascript

What I need is as follows: The blue area should resize when the browser window resizes. The header must be visible at all times. The blue area should start right after the header ends, not overlapping or appearing above it. The blue area should end befor ...

"Jsoup interprets certain characters in a unique way during parsing

I attempted to parse this HTML file using Jsoup: <html><body>Maître Corbeau, sur un arbre perché</body></html> The line of code I used was: Document document = Jsoup.parse(input, "UTF-8"); However, when I tried to print the do ...

Adding a data attribute to a Material-UI Button: A step-by-step guide

I'm trying to include a custom data attribute in the Material-UI Button Component as shown here. Here's what I attempted: <Button inputProps={{ 'data-testid'='clickButton' }} > Click </Button However, this approach ...

Enhancing the visual appeal of a standard jQuery slider with thumbnails

Recently, I incorporated the Basic jQuery slider into my website, which can be found at . As a novice in jQuery but well-versed in HTML and CSS, I have managed to make it work seamlessly on my site. However, I am curious to know if there is a way to displa ...

Place the HTML images in the center of the page

I would like the two images to be centered on the page. Please refer to this visual representation for guidance: Here is the code snippet: * { box-sizing: border-box; } .column { float: left; width: 28%; height: 28%; padding: 5px; } /* Cle ...

What is the best way to ensure bidirectional text appears correctly when two conflicting languages are combined, ensuring explicit directionality is set?

As I work on localization implementation, I encounter an issue with the directionality of mixed characters on the page. The text content is stored in a json file and inserted into the DOM using a Vue.js template. While individual characters display corre ...

Bootstrap creates a small and calculated width for elements

Currently, I am integrating the react-datepicker plugin into my project alongside Bootstrap 3. Upon implementation, I have noticed that the size of the datepicker on my website appears to be smaller than the examples provided in the plugin demos. It seems ...

Aligning Elements in the CSS Bootstrap Grid

Struggling to achieve perfect center alignment of an HTML element using the Bootstrap grid framework. Here's the current code: <div id="rentals" class="container pb-4"> <div class="row pt-5 mt-5 mb-4"> ...

What causes one CSS file's properties to be inherited by another CSS file in a React application?

I'm puzzled as to why my hero section file seems to be adopting the styling from the navbar CSS file. I do understand that the index.css file sets properties for the entire app, but in my case, I have separate CSS files for different components instea ...

Troubles with horizontal list incompatibility in Internet Explorer 6 and 7

I am facing an issue with displaying an unordered list in IE6+7. The problem arises when styling the list items with specific width and height properties, causing IE to stack the items vertically instead of horizontally. Below is my code snippet: For live ...

Tips for designing adjustable text in bootstrap 4

Could someone please assist me with making text responsive using Bootstrap 4? I have searched everywhere but it's strange to see that there are no tutorials on this topic. Below are my codes in case you would like to provide guidance. <div class=" ...

Reduce the dimensions of a CSS attribute automatically

Displayed below is the image with a width of 192 and height of 109: <a href="https://www.blogger.com/u/1/blogger.g?blogID=4402911157743442948#"><img alt="" class="thumbnail" height="109" src="https://2.bp.blogspot.com/-E5ftfbCCgkw/XjnLpO347cI/AAA ...

Using JQuery to locate and substitute occurrences of HTML elements throughout my webpage

Looking for assistance with a JQuery search and replace task involving multiple instances of HTML within a specific DIV element on my webpage. Specifically, I need to change certain items in the textbox to a simpler display format. Here is a snippet of th ...

Capture audio using a web browser

Currently working on a project to create a platform for recording sounds. I'm aiming to incorporate a meter that measures the volume of the sound. Despite extensive research, I haven't been able to discover an HTML5 solution compatible with all b ...

I'm curious as to why a webpage tends to load more quickly when CSS files are loaded before script files. Can anyone shed some

While watching a video, I came across some concepts that were a bit difficult for me to grasp. The video mentions that scripts are 'serialized' and can block subsequent files from loading. According to this explanation, Script 1 would load first ...

The video on my site is refusing to play

I'm having an issue with a 2-second video that is not playing, yet when I tried a 10-second video it worked perfectly. Why is this happening? Could it be that HTML does not support videos that are shorter than 1-2 seconds? It seems like it's onl ...