Crafting a dynamic CSS 'trail' effect when hovering

I am attempting to create a visually appealing CSS menu using primarily CSS, with just a touch of jQuery as well:

Here is the concept:

+------------------------+
|                        |
|                        |
|         +---+          |
|         |   |          |
|         |___|          | <-- Hover over this central piece
|                        |
|                        |
|                        |
+------------------------+

+------------------------+
|     _                  |
|    |\                  | <-- All elements move towards the top of the screen
|      \  +---+          |
|         |   |          |
|         |___|          |
|                        |
|                        |
|                        |
+------------------------+

...and so on...

The plan involves four div children, each positioned at 90-degree intervals from the center. However, I am trying to figure out a way to determine the angle/position in jQuery, which has proven to be challenging.


Similar design:


If there were six child divs, they would be evenly spaced out at 60-degree intervals.


I will also be incorporating animations between them, leading me to experiment with rotations, but I have not been successful:

Fiddle


My questions are:

  • (A): How can I rotate the divs by a specified angle or distance relative to their parent using jQuery?

  • (B): How can I reset the animation upon hover out?


Other similar implementations:

  • Here
  • This one, although it utilizes Sass (which is not desired)

Answer №1

Trying out a different method can yield a slightly altered result. Adjusting the timing of the setTimeout and transition can change the behavior.

Check out the code snippet here

+ function() {
  var to;
  $(".wrap").on('mouseenter', function() {
    var circles = $(this).children();
    var degree = (2 * Math.PI) / circles.length; //calc delta angle
    var transforms = [];

    // Calculate the position for each circle
    circles.each(function(index) {
        var x = 100 * Math.cos(-0.5 * Math.PI + degree * (-1 * index - 0.5));
        var y = 100 * Math.sin(-0.5 * Math.PI + degree * (-1 * index - 0.5));

      transforms.push('translate(' + x + 'px,' + y + 'px)');
    });

    // Function to moves all the circles
    // We'll pop a circle each time and than call this function recursively
    function moveCircles() {
      var transform = transforms.shift();
      circles.css('transform', transform);

      circles.splice(0, 1);
      if (circles.length) to = setTimeout(moveCircles, 400);
    }

    moveCircles();
  });

  $(".wrap").on('mouseleave', function() {
    var circles = $(this).children().css('transform', '');
    clearTimeout(to);
  });
}();
   .wrap {
     height: 300px;
     width: 300px;
     background: red;
     position: relative;
     transform-origin: center center;
     transition: all 0.8s;
   }
   .circle {
     transition: all 0.8s;
     position: absolute;
     height: 50px;
     width: 50px;
     text-align: center;
     line-height: 50px;
     top: calc(50% - 25px);
     left: calc(50% - 25px);
     background: tomato;
     border-radius: 50%;
   }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
  <div class="circle">1</div>
  <div class="circle">2</div>
  <div class="circle">3</div>
  <div class="circle">4</div>
  <div class="circle">5</div>
  <div class="circle">6</div>
</div>

Answer №2

function rotateImage($this, $circle, angle) {
    $this.animate({
        rotation: angle
    }, {
        step: function(now, fx) {
            $this.css({
                transform: 'rotate(' + now + 'deg)'
            });
            $circle.css({
                transform: 'translate(-50%, -50%) rotate(' + -now + 'deg)'
            });
        }
    });
}

$('.container').hover(function() {
    var $this = $(this),
        $circleWrappers = $this.find('.imageWrapper'),
        angleOffset = 360 / $circleWrappers.length,
        angle = - angleOffset / 2,
        distance = Math.min($this.width(), $this.height()) / 2;
    
    $circleWrappers.each(function() {
        var $this = $(this),
            $circle = $(this).find('.image');
        $circle.animate({ top: -distance });
        rotateImage($this, $circle, angle);
        angle -= angleOffset;
    });
}, function() {
    var $this = $(this),
        $circleWrappers = $this.find('.imageWrapper');
    
    $circleWrappers.each(function() {
        var $this = $(this),
            $circle = $(this).find('.image');
        $circle.animate({ top: 0 });
        rotateImage($this, $circle, 0);
    });
});
.container {
    position: relative;
    background-color: #cccccc;
    width: 400px;
    height: 400px;
    transition:all 0.8s;
    transform-origin: center center;
}
.imageWrapper {
    display: inline-block;
    position: absolute;
    left: 50%;
    top: 50%;
}
.image {
    position: absolute;
    width: 80px;
    height: 80px;
    border-radius: 40px;
    background-color: white;
    box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
    line-height: 80px;
    text-align: center;
    font-family: arial;
    font-size: 42px;
    font-weight: bold;
    transform: translate(-50%, -50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
    <div class="imageWrapper"><div class="image">1</div></div>
    <div class="imageWrapper"><div class="image">2</div></div>
    <div class="imageWrapper"><div class="image">3</div></div>
    <div class="imageWrapper"><div class="image">4</div></div>
</div>

JSFiddle Link

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

Update the iframe URL to direct the user to a new tab instead of opening a popup

I have created the following script, but I am facing a challenge as I realize that the URL I want to use opens in a new tab instead of just forwarding: <script> function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.sp ...

Struggling to find the right look for identical items

I'm currently working on a project where I need to identify and hide duplicate values in a table. The goal is to only display unique values in the first column and hide any duplicates from view. However, I'm running into an issue when trying to h ...

hide the side menu automatically - wordpress

is the official website created using a WordPress platform. Upon visiting the site, you will immediately notice a prominent "showcase" banner positioned right below the navigation bar. On the right side, there are additional posts that users can choose t ...

Tips for minimizing the gap between two rows in a table with a set height

I've created a table, but I'm facing an issue where the space between two elements is too large when there are multiple items in the loop. How can I decrease the spacing between these elements? <table width="100%" height="280" border="1" st ...

Is it possible to configure the jQuery datepicker to function without displaying the year?

I am looking to incorporate a datepicker into a project centered around historical events on specific dates. The concept is for users to select a day, such as "Nov. 20," and have the project display historical events from various years on that same day. ...

What is the best way to adjust the dimensions of an image using CSS?

I've been struggling to adjust the dimensions of my image using CSS by specifying a width and height attribute. However, instead of resizing the picture, it seems to simply zoom in on the existing image. For instance, I have an image that is 90px by ...

The sequence of divs in a language that reads from right to left

Is there a way in HTML to designate a set of divs so that they automatically align from left to right for languages that read left to right, and alternatively, flow from right to left for languages that read right to left? This means that the direction of ...

Dealing with errors in jQuery when handling JSON

Currently, I am utilizing jQuery's ajax feature to transmit JSON to a PHP script and then acquire a JSON set of values for processing on the front end. The PHP script is properly sending the JSON data, and I am successfully able to display the JSON o ...

Performing the AJAX request prior to the document being fully loaded

What I need is for an AJAX call to be made before the document is ready, and then use the response from the AJAX call to update certain HTML elements. This is what I currently have: var ajaxget = $.ajax({ type: 'GET', url:'/xxx ...

Struggling to create a search bar and dropdown menu that adapts to different

Currently, I'm working on creating an advanced search bar and came across this template here. Everything seems to be functioning properly except for the fact that the search bar and dropdown menu are not fully utilizing the entire width of 100%. I wou ...

Using AJAX to delete items from the personalized shopping cart on your WooCommerce website

I am encountering an issue with removing products from the cart. Although my code successfully removes the product in ajax, it fails to refresh the cart. Here is the code snippet I am working with: add_filter('woocommerce_add_to_cart_fragments', ...

Developing a Multi-Faceted Array Utilizing SQL Data

The requirement of the plugin I am using is to provide it with an array structure in JavaScript that looks like this: var data = [ { "id": 1, "name": "University1", "list": [ {"id": 1, "name": "Dorms", "list": ...

The jquery function is not operating as anticipated

I wrote the following code to toggle a class for a div. <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <html> <head> </head> <body> <div class="members-section " id="a ...

What is the best way to split an input field into distinct fields for display on the screen?

Take a look at this image: https://i.stack.imgur.com/LoVqe.png I am interested in creating a design similar to the one shown in the image, where a 4 digit one-time password (OTP) is entered by the user. Currently, I have achieved this by using 4 separate ...

Questions and confusion surrounding Ajax with Jquery

What is the purpose of including jquery.mn.js file in the SCRIPT tag for form validation and other jquery and ajax applications? Is there a specific location to download this file, and where should it be saved on a personal computer? ...

AJAX Response Type in ASHX Handler

Currently, I am working on a webpage that requires communication with a SQL server. To ensure portability and avoid using ASP on the IIS 7 server, I have decided to write the page in pure HTML. For the server-side tasks, I am employing a generic handler (A ...

Toggle the selection of a div by clicking a button in AngularJS with a toggle function

I have several div elements on a webpage. Each div contains a button! When the button is clicked for the first time: The border color of the div will change to blue (indicating the div is now selected). The "ok" button will be hidden (leaving only t ...

Aligning elements of unknown width within a container of a specified width

Currently struggling to find a resolution to the following issue: Trying to create a navigation bar using a ul element set to a specific width of 530px with multiple li items nested inside. The goal is to have the li items evenly fill the 530px width wit ...

Issue with Foundation 6 not triggering the change.zf.slider event

Hey there, this is my first time posting and I could really use some help... I'm struggling to make the $("[data-slider]").on('change.zf.slider', function(){}); event trigger. I've attempted using the id of the element like so $(" ...

Close the gap in the CSS for the image tag

I am facing an issue. Whenever I include an img Tag in my HTML File, there is a Gap around the tag. It is neither margin nor padding. I wonder what it could be? Could someone please assist me in removing the gap with CSS? <img src="../images/modules/ ...