CSS3 transition applied to a jQuery direction-aware hover effect

I'm encountering difficulties making direction-aware hover and css transitions function correctly. Specifically, I am attempting to create a grid of elements with front and back faces, and on hover, have a css transition that flips the element to display the back face.

Here's an example of the transition (without direction-aware): fiddle

Currently, no matter how your mouse enters an element, it always flips up. My goal is to have it flip in the direction the mouse enters or exits.

Examples:

https://i.sstatic.net/Fm9Qf.gif https://i.sstatic.net/MJIkn.gif

Below is my attempt at implementing direction-aware: fiddle

I am using jQuery to add classes related to the mouse's direction in/out.

.hover-in-top {}
.hover-in-right {}
.hover-in-bottom {}
.hover-in-left {}

.hover-out-top {}
.hover-out-right {}
.hover-out-bottom {}
.hover-out-left {}

While the direction-aware example somewhat works, there are significant glitches that I can't seem to figure out. (I've been overthinking this and my brain feels overloaded.)

I hope this explanation makes sense. Thank you.

Answer №1

I have made some adjustments to your query.

After modifying a few transitions, I switched them to animations

$('.box-container .box').each(function() {
    $(this).on('mouseenter mouseleave', function(e) {
        var $this = $(this),
            width = $this.width(),
            height = $this.height();

        var x = (e.pageX - $this.offset().left - (width / 2)) * (width > height ? (height / width) : 1),
            y = (e.pageY - $this.offset().top - (height / 2)) * (height > width ? (width / height) : 1);

        // top = 0, right = 1, bottom = 2, left = 3
        var dir_num = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4,
            directions = ['top', 'right', 'bottom', 'left'];

        // If mouse enter
        if (e.type === 'mouseenter') {
            // Remove all hover out classes
            $this.removeClass(function(index, css) {
                return (css.match(/(^|\s)hover-out-\S+/g) || []).join(' ');
            });

            // Add in direction class
            $this.addClass('hover-in-' + directions[dir_num]);
        }


        // If mouse leave
        if (e.type === 'mouseleave') {
            // Remove all hover in classes
            $this.removeClass(function(index, css) {
                return (css.match(/(^|\s)hover-in-\S+/g) || []).join(' ');
            });

            // Add out direction class
            $this.addClass('hover-out-' + directions[dir_num]);
        }
    });
});
* {
    box-sizing: border-box;
}

.box-container {
    padding: 20px;
    width: 600px;
}
.box-container:after {
    content: '';
    display: block;
    clear: both;
}
.box-container .box {
    float: left;
    width: 50%;
    height: 200px;
    position: relative;
    perspective: 600px;
    border: 1px solid transparent;
}
.box-container .box .front, .box-container .box .back {
    float: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    transform-style: preserve-3d;
    backface-visibility: hidden;
    transition: all 1s ease-in-out;
    color: white;
    font-size: 60px;
}
.box-container .box .front {
    background: blue;
    transform: rotateX(0) rotateY(0);
    z-index: 900;
}
.box-container .box .back {
    background: red;
    z-index: 800;
}
.box-container .box:hover .front {
    z-index: 900;
}
.box-container .box:hover .back {
    z-index: 1000;
    transform: rotateX(180) rotateY(0);
}

.box-container .box.hover-in-top .front,
.box-container .box.hover-out-bottom .back {
    transform: rotateX(-179deg) rotateY(0);
}
.box-container .box.hover-in-top .back,
.box-container .box.hover-out-bottom .front {
    animation: Xminus 1s ease-in-out;
}
@keyframes Xminus {
    from {transform: rotateX(179deg) rotateY(0);}
    to   {transform: rotateX(  0deg) rotateY(0);}
}

.box-container .box.hover-in-bottom .front,
.box-container .box.hover-out-top .back {
    transform: rotateX(179deg);
}
.box-container .box.hover-in-bottom .back,
.box-container .box.hover-out-top .front {
    animation: Xplus 1s ease-in-out;
}
@keyframes Xplus {
    from {transform: rotateX(-179deg) rotateY(0);}
    to   {transform: rotateX(   0deg) rotateY(0);}
}

.box-container .box.hover-in-right .front,
.box-container .box.hover-out-left .back {
    transform: rotateY(-179deg);
}
.box-container .box.hover-in-right .back,
.box-container .box.hover-out-left .front {
    animation: Yminus 1s ease-in-out;
}
@keyframes Yminus {
    from {transform: rotateX(0deg) rotateY(179deg);}
    to   {transform: rotateX(0deg) rotateY(  0deg);}
}

.box-container .box.hover-in-left .front,
.box-container .box.hover-out-right .back {
    transform: rotateY(179deg);
}

.box-container .box.hover-in-left .back,
.box-container .box.hover-out-right .front {
    animation: Yplus 1s ease-in-out;
}
@keyframes Yplus {
    from {transform: rotateX(0deg) rotateY(-179deg);}
    to   {transform: rotateX(0deg) rotateY(  0deg);}
}
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box-container">
    <div class="box">
        <div class="front">FRONT</div>
        <div class="back">BACK</div>
    </div>
    <div class="box">
        <div class="front">FRONT</div>
        <div class="back">BACK</div>
    </div>
    <div class="box">
        <div class="front">FRONT</div>
        <div class="back">BACK</div>
    </div>
    <div class="box">
        <div class="front">FRONT</div>
        <div class="back">BACK</div>
    </div>
</div>

The drawback of using animations is that the animation may be disrupted if you move away from the div before it completes

However, if you move slowly and remain on the divs until the animation finishes, it should function properly.

I am optimistic that someone will discover a more effective solution

Answer №2

In my opinion, avoiding CSS transitions is the most effective approach to solving this problem.

By incorporating jQuery's animate function and leveraging its animations queue feature, you can easily achieve synchronized animations for a seamless user experience.

I have made adjustments to your code example to demonstrate how to animate the transition using JavaScript instead of CSS.

Check out the updated code snippet here.

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

Ways of accessing an array within an if statement

I have a dashboard with admin privileges for my application. In this dashboard, the admin can select a user from a dropdown list. Once a user is selected, I make an AJAX call to retrieve the user's data and store it in a variable named $result. Howeve ...

Tips for creating a scale animation using HTML5 Canvas

I am currently developing a canvas whiteboard tool and I have reached the stage where I am focusing on implementing the Zoom In and Zoom Out feature. While the functionality is working fine, I would like to enhance it with smooth animations for scaling. H ...

What measures do websites such as yelp and urbandictionary implement to avoid multiple votes from unregistered users?

It is interesting to note that on urbandictionary, you do not need to be logged in to upvote a definition. For example, if you visit and upvote the first word, it will record your vote. Even if you open an incognito window and try to upvote again, or use ...

Is there a way to transform a local array into remote JSON data?

I am attempting to retrieve an array from a remote server that is connected to a dynamic database. From what I have gathered on Ionic forums, it seems that I need to utilize the $http function from AngularJS. However, since I am new to AngularJS, the curr ...

Utilizing TypeDoc to Directly Reference External Library Documentation

I am working on a TypeScript project and using TypeDoc to create documentation. There is an external library in my project that already has its documentation. I want to automatically link the reader to the documentation of this external library without man ...

tips for scrolling divs horizontally within the main container

I've been attempting to scroll horizontally, but even though the scroll bar is visible, it's not functioning. Here's the code: <!DOCTYPE html> <html> <head> <title>qwe</title> </head> <body> < ...

JavaScript: Targeting elements by their tag name within a designated container

When working with PHP, it is possible to use the getElementsByTagName method on any DOM object. However, this concept does not seem to exist in JavaScript. For example, if we have a specific node stored in the variable detailsNode, attempting to use detai ...

Node.js Express: Breaking Down Your Application into Modules

Currently, I am working on an express app and have the following code setup: MainApp.js const express = require('express'); const routes = require('./routes') const mainApp = express(); mainApp.listen(3000, () => { console.l ...

How can I use Ajax to open views in Asp.net Core 3.1?

Why is the view not being displayed even though there is no error? jQuery : $('#edit_button').on("click", function () { var instance = $('#jstree').jstree("get_selected"); if (instance != 0) ...

Can parameters be passed in an ajax request with a dynamic parameter name in asp.net?

Can someone help me with an issue I am facing with ajax requests? I have a post ajax request in asp.net where I pass parameters. When I change the parameter name in the code behind (aspx.cs), the request fails to post. However, when I tried the same with M ...

Eliminating shadow effects caused by excessive scrolling on Android browsers and Cordova platforms

Mysterious Scroll Shadow Issue My webpage is displaying a shadow when I scroll too far up or down. I am using Cordova to show my HTML, but I have noticed this problem on other sites in the Chrome browser as well. Could this be a CSS property causing the i ...

When the function is clicked, an error occurs that says: "return is a reserved word"

I am attempting to trigger a popup window when clicking on the link button, but I keep getting an error stating that "return" is a keyword and expecting an identifier. I'm using ASP.NET for this functionality. <asp:LinkButton ID="CommentAction" h ...

Unlocking the Secret: Retrieving Click Event Values from a jQuery Function

Is there a way to retrieve the onclick event value change in jQuery when clicking on a DIV? $("ul li").click(function(){ var newValue = $(this).val(); }); $(function(){ alert(newValue); }); ...

When the next button is clicked, the button content disappears

I am struggling with a problem involving two buttons that store tables. The issue is, I want the table to disappear when the second button is clicked and show the contents of the second button immediately after clicking it once, rather than having to click ...

Tips for transforming a nested for-loop into a recursive function

Trying to work with Memcached data in Node.js is proving to be a challenge due to the asynchronous nature of the language. My goal is to store all retrieved results in an object. This is how I would typically approach it: for( x = startX; x <= endX; x ...

Decode JavaScript once AJAX has been loaded

Having an index.php page that loads content in a div "container" using ajax. I am facing an issue where a part of the javascript inside one of my html includes is not working when making an ajax request. The content loads, but the javascript does not execu ...

Styling the Padding of MUI Select Component in ReactJS

Currently, I am facing an issue with the Material UI Select component where I am trying to decrease the padding within the element. The padding seems to be a property of one of the subclasses .MuiOutlinedInput-input, but my attempts to change the padding h ...

Is it viable to create an onClick event for the text content within a text area?

I'm working on a project that involves displaying XML data in a textarea and creating an onClick event for the content within the textarea. For example: <textarea>Hello Web, This is a simple HTML page.</textarea> My goal here is to cre ...

I'm struggling to grasp the concept of State in React.js

Even though I'm trying my best, I am encountering an issue with obtaining JSON from an API. The following error is being thrown: TypeError: Cannot read property 'setState' of undefined(…) const Main = React.createClass({ getInitia ...

The link in the HTML code has been prevented from opening in a new

echo "<tr><th align='left'><a href=\"$email\">$name</a></th> I recently transformed a PHP Email App into a saving app. However, I am encountering an issue with opening links within the application. You ca ...