Spin a child element by clicking on its parent component

I am looking to create a unique animated effect for the arrows on a button, where they rotate 180 degrees each time the button is clicked.
The concept involves rotating both sides of the arrow (which are constructed using div elements) every time the containing div that houses these arrow divs is clicked.

I attempted to achieve this using Toggle but encountered some issues. Below is my code:

.button-back {
  width: 50px;
  height: 50px;
  background-color: #fff;
  border-radius: 100%;
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: background-color 0.3s;
  cursor: pointer;
}

.button-back:hover {
  background-color: #2da6ff;
}

.left {
  left: 5%;
}

.right {
  right: 5%;
}

#left-top {
  margin-bottom: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(-45deg);
  left: 30%;
  background: #e2e2e2;
  z-index: 3;
}

#left-bottom {
  margin-top: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(45deg);
  left: 30%;
  background: #e2e2e2;
  z-index: 3;
}

#right-top {
  margin-bottom: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(45deg);
  left: 40%;
  background: #e2e2e2;
}

#right-bottom {
  margin-top: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(-45deg);
  left: 40%;
  background: #e2e2e2;
}
<div class="button-back left">
  <div id="left-top"></div>
  <div id=left-bottom></div>
</div>
<div class="button-back right">
  <div id="right-top"></div>
  <div id="right-bottom"></div>
</div>

Thank you!

Answer №1

My solution includes adding an "animated" class to create a slow rotation animation in 0.5 sec.

.animated {
  -moz-transition: transform 0.5s;
  -webkit-transition: transform 0.5s;
  transition: transform 0.5s;
}

I also implemented a script to handle the rotation of each arrow line.

$(document).ready(function() {
  var leftdegplus = -45;
  var leftdegminus = 45;
  var rightdegplus = 45;
  var rightdegminus = -45;
  $(".left").click(function() {
    leftdegplus = leftdegplus + 180;
    $(this).find("#left-top").css("transform", "rotate(" + leftdegplus + "deg)");

    leftdegminus = leftdegminus - 180;
    $(this).find("#left-bottom").css("transform", "rotate(" + leftdegminus + "deg)");

  });
  $(".right").click(function() {

    rightdegplus = rightdegplus - 180;
    $(this).find("#right-top").css("transform", "rotate(" + rightdegplus + "deg)");

    rightdegminus = rightdegminus + 180;
    $(this).find("#right-bottom").css("transform", "rotate(" + rightdegminus + "deg)");
  });


});

This snippet contains the full code for creating the rotating arrow buttons:

$(document).ready(function() {
  var leftdegplus = -45;
  var leftdegminus = 45;
  var rightdegplus = 45;
  var rightdegminus = -45;
  $(".left").click(function() {
    leftdegplus = leftdegplus + 180;
    $(this).find("#left-top").css("transform", "rotate(" + leftdegplus + "deg)");

    leftdegminus = leftdegminus - 180;
    $(this).find("#left-bottom").css("transform", "rotate(" + leftdegminus + "deg)");

  });
  $(".right").click(function() {

    rightdegplus = rightdegplus - 180;
    $(this).find("#right-top").css("transform", "rotate(" + rightdegplus + "deg)");

    rightdegminus = rightdegminus + 180;
    $(this).find("#right-bottom").css("transform", "rotate(" + rightdegminus + "deg)");
  });


});
.button-back {
  width: 50px;
  height: 50px;
  background-color: #fff;
  border-radius: 100%;
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: background-color 0.3s;
  cursor: pointer;
}

.button-back:hover {
  background-color: #2da6ff;
}

.left {
  left: 5%;
}

.right {
  right: 5%;
}

#left-top {
  margin-bottom: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(-45deg);
  left: 30%;
  background: #e2e2e2;
  z-index: 3;
}

#left-bottom {
  margin-top: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(45deg);
  left: 30%;
  background: #e2e2e2;
  z-index: 3;
}

#right-top {
  margin-bottom: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(45deg);
  left: 40%;
  background: #e2e2e2;
}

#right-bottom {
  margin-top: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(-45deg);
  left: 40%;
  background: #e2e2e2;
}

.animated {
  -moz-transition: transform 0.5s;
  -webkit-transition: transform 0.5s;
  transition: transform 0.5s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button-back left">
  <div class="animated " id="left-top"></div>
  <div class="animated " id=left-bottom></div>
</div>
<div class="button-back right">
  <div class="animated " id="right-top"></div>
  <div class="animated " id="right-bottom"></div>
</div>

Answer №2

Give this approach a shot!)

const leftButton = document.querySelector('.left');
const arrowElements = leftButton.children;

function removeRotation(){
  arrowElements[0].classList.remove('rotate-top');
  arrowElements[1].classList.remove('rotate-bottom');
}

function rotateArrows(){
  arrowElements[0].classList.add('rotate-top');
  arrowElements[1].classList.add('rotate-bottom');
  setTimeout(removeRotation, 200);
}

leftButton.addEventListener('click', rotateArrows);
.button-back {
  width: 50px;
  height: 50px;
  background-color: #fff;
  border-radius: 100%;
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: background-color 0.3s;
  cursor: pointer;
}

.button-back:hover {
  background-color: #2da6ff;
}

.left {
  left: 5%;
}


#left-top {
  margin-bottom: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(-45deg);
  left: 30%;
  background: #e2e2e2;
  z-index: 3;
}

#left-bottom {
  margin-top: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(45deg);
  left: 30%;
  background: #e2e2e2;
  z-index: 3;
}


.rotate-top{
  animation: rotate-center-top 0.3s linear both;
}
.rotate-bottom{
  animation: rotate-center-bottom 0.3s linear both;
}


@keyframes rotate-center-top {
  0% {
            transform: rotate(0);
  }
  100% {

            transform: rotate(135deg);
  }
}
@keyframes rotate-center-bottom {
  0% {
            transform: rotate(0);
  }
  100% {
            transform: rotate(-135deg);
  }
}
<div class="button-back left">
  <div id="left-top"></div>
  <div id=left-bottom></div>
</div>

Answer №3

To accomplish this task, JavaScript is necessary.

var leftBtn = document.getElementById("left");

var rightBtn = document.getElementById("right");

leftBtn.addEventListener("click", function(e) {

  if (e.target.id !== "left") return;

  e.target.children["0"].style.transition = "0.3s transform linear";

  e.target.children["1"].style.transition = "0.3s transform linear";

  e.target.children["0"].style.transform = "rotate(140deg)";

  e.target.children["1"].style.transform = "rotate(-140deg)";

  setTimeout(function() {

    e.target.children["0"].style.transition = "0s all linear";

    e.target.children["1"].style.transition = "0s all linear";

    e.target.children["0"].removeAttribute("style");

    e.target.children["1"].removeAttribute("style");

  }, 510);

});

rightBtn.addEventListener("click", function(e) {

  if (e.target.id !== "right") return;

  e.target.children["0"].style.transition = "0.3s transform linear";

  e.target.children["1"].style.transition = "0.3s transform linear";

  e.target.children["0"].style.transform = "rotate(-140deg)";

  e.target.children["1"].style.transform = "rotate(140deg)";

  setTimeout(function() {

    e.target.children["0"].style.transition = "0s all linear";

    e.target.children["1"].style.transition = "0s all linear";

    e.target.children["0"].removeAttribute("style");

    e.target.children["1"].removeAttribute("style");

  }, 510);

});
.button-back {
  width: 50px;
  height: 50px;
  background-color: #fff;
  border-radius: 100%;
  position: absolute;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: background-color 0.3s;
  cursor: pointer;
}

.button-back:hover {
  background-color: #2da6ff;
}

.left {
  left: 5%;
}

.right {
  right: 5%;
}

#left-top {
  margin-bottom: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(-45deg);
  left: 30%;
  background: #e2e2e2;
  z-index: 3;
}

#left-bottom {
  margin-top: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(45deg);
  left: 30%;
  background: #e2e2e2;
  z-index: 3;
}

#right-top {
  margin-bottom: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(45deg);
  left: 40%;
  background: #e2e2e2;
}

#right-bottom {
  margin-top: 3px;
  width: 15px;
  height: 3px;
  position: relative;
  transform: rotate(-45deg);
  left: 40%;
  background: #e2e2e2;
}
<div class="button-back left" id="left">
  <div id="left-top"></div>
  <div id=left-bottom></div>
</div>
<div class="button-back right" id="right">
  <div id="right-top"></div>
  <div id="right-bottom"></div>
</div>

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

CSS style for tables with inner gutters only

I am attempting to create a table layout with spacing between cells but without any external space for the cells at the border. I have written a simple code snippet to illustrate my issue: html, body, div, table, caption, tbody, tfoot, thead, tr, th, td ...

State update failing to modify arrays

Shown below is an array that contains boolean values: const [state, setState] = React.useState({ [`${"checkedA"+index}`]: false, [`${"checkedB"+index}`]: false, [`${"checkedC"+index}`]: false, [`${"checkedD"+index}`]: false, }); ...

Processing XML Files Using Nodejs

Apologies for the rookie question, but I'm feeling a bit confused... I'm attempting to pull "objects" from an XML file so that I can modify and incorporate them into a database. I attempted using xml2js and now have a JavaScript object, but I&ap ...

What could be the reason for Angular showing the raw HTML code instead of

I'm currently diving into Angular and encountering an issue where my HTML isn't properly displaying the values I've set. It appears to only show the raw HTML. Here's a snippet from my HTML page: <p>to-do-items works!</p> < ...

What is the best way to upgrade to a specific version of a child dependency within a module?

npm version: 7.24.2 Looking for assistance on updating a child dependency. The dependency in question is: vue-tel-input This dependency relies on libphonenumber-js with version ^1.9.6 I am aiming to update libphonenumber-js to version ^1.10.12. I have ...

Create an Ajax request function to execute a PHP function, for those just starting out

I came across a JS-Jquery file that almost meets my needs. It currently calls a PHP function when a checkbox is clicked, and now I want to add another checkbox that will call a different PHP function. My initial attempt was to copy the existing function a ...

The declaration file for the 'react' module could not be located

I was exploring Microsoft's guide on TypeScript combined with React and Redux. After executing the command: npm install -S redux react-redux @types/react-redux I encountered an error when running npm run start: Type error: Could not find a decla ...

What is the method to create a polygon in its entirety by utilizing a for loop within Javascript?

After successfully using the Canvas of HTML to draw a convex polygon, I encountered an issue. In the provided code snippet, t2 represents an array of points with getX() and getY() methods. The drawing function performs as expected until it reaches the seg ...

Guide: Previewing uploaded images with HTML and jQuery, including file names

Any constructive criticism and alternative methods for accomplishing this task are welcomed. I am currently working on writing jQuery code that will allow users to preview file(s) without reloading the DOM. To achieve this, I have been using .append() to ...

The grayscale effect is not functioning on the default web browser of an Android device

I have implemented a grayscale effect for an image using the following CSS code snippet: img.grayscale { filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\&apo ...

Choose all elements by their class except for a particular container defined by the parent element's ID

Can you provide an example of translating the function below into utilizing the .not method (or not selector)? $(".CLASS").filter(function(i, e){ return (e.parentNode.id != "ID"); } ...

The css cropping issue with sprite image is not being resolved

I'm currently working on creating a sprite image for the bottom links on our media page, but I seem to be having trouble getting the image to crop correctly. Can anyone point out where I may be making a mistake? CSS .footer{ position:absolute; ...

Launching a call to action through Ajax in Zend Framework triggers a redirect, but subsequent calls prove to be effective

I've encountered an intriguing issue that I'm hoping someone else has come across and resolved before. In this particular application, I have implemented a 'change my password' option for users. If a user forgets their password, they c ...

Is there a way for a Vue component to interact with a button or checkbox in order to dynamically update tooltip content and button style using a function?

Is it possible for a Vue component to trigger button clicks or checkbox checks in order to update tooltip text and button color using a function? Despite the presence of a handle() function in the code provided, these changes are not currently taking effec ...

Parameterized query causing JavaScript error

As I struggle with this issue for more than a day now, a scenario unfolds where a user clicks on a link of a book name triggering me to read that book's name. Subsequently, an Ajax request is made to a Jersey resource within which a method in a POJO c ...

Is there a way to utilize req.query, req.params, or req.* beyond its original scope without the need to store it in a database?

Looking to streamline my code and apply the DRY pattern, I've been working on creating a helper function for my express http methods. The structure of each method is similar, but the req.params format varies between them. Here's how I attempted t ...

Issue with Laravel ReactJs: My changes in the ReactJs file are not being reflected on the website

I've been utilizing Reactjs within Laravel. Recently, I made some modifications to my React Component and upon refreshing my browser, the changes did not reflect. Here are the files involved: resources/views/welcome.blade.php <!doctype html&g ...

Retrieving AJAX content once it has finished loading

Apologies for my poor English. I have a function to handle ajax requests like this: $(document).on("click", ".ajax", function(e){ //dynamic content here, getting the href value from links. }); Now I need to manipulate the content of the ajax response AF ...

Display a D3 Collapsible Tree visualization using information stored in a variable

I am currently working on an app that requires the display of a collapsible tree graph using D3. The data needed for this graph is not stored in a file, but rather within the database. It is retrieved through an Ajax call to a rest service and then passed ...

Customized Error Handling Function for Ajax Requests

I have a function that works perfectly, but I need to add six more buttons without repeating code. I want each callback to be customizable, with different text for each scenario (e.g. displaying "Please Log In" if the user is not an admin). How can I make ...