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

Understanding how to implement action logic in React Redux to control visibility of specific categories

Seeking guidance on how to implement action logic for displaying and hiding elements based on user interaction. Currently, all categories and subcategories are shown at once, but I would like them to be displayed only when a user clicks on them. When a use ...

Utilizing React Refs to Retrieve Value from HTML Select Element

I am currently working on a form that includes the use of an HTML select element. <select className="form-control" id="ntype" required > <option value = "">None</option> <option value = "1">1</option> < ...

Experiencing odd behavior with my Dash App when using CSS grid on it

Seeking assistance with my coding issue, I believe sharing my code from Github would be the most efficient way to address it. An exclusive branch named css_problem_branch has been created to showcase the problem at hand. To access the Github repository, p ...

Creating a conditional npm script that depends on the output of another: a step-by-step guide

I've encountered this problem before while setting up npm scripts, and I haven't been able to find a solution yet. I'm hoping to make the solution compatible with both Mac and Windows environments. I'm working on splitting up the logic ...

Introducing Row Offset Enhancement

I am working on a code to create a custom "table" because I require some more intricate features that a regular table cannot provide. <div class="container"> <cfloop index="x" from="1" to="5"> ...

Transform the string response in a websocket message into JSON format

When receiving a websocket message, I often encounter a response in the form of a string like this: odds.1:[{"id":1,"marketType":10,"name":"Double chance","status":"HandedOver","specifiers":"","Outcomes":[]},{"id":2,"marketType":11,"name":"Draw no bet", ...

The redirect link to Facebook Messenger is functional on desktop browsers but experiences difficulties on mobile browsers

Currently, I am facing an issue with redirecting from a webpage to an m.me/?ref= Facebook link that points to a Facebook Page. The redirection works smoothly on the Desktop Browser and opens the Facebook Messenger as expected. However, when attempting the ...

HTML forms are larger in size on web pages than in Internet Explorer

https://i.stack.imgur.com/bUPtm.png I have posted the issue, and it is predominantly visual in nature. When viewed on a web browser within a C++ interface, the HTML appears significantly distorted. ...

Guide to configuring Javascript as a Blade template for integration into an API endpoint

I am currently developing a Javascript program that is loaded through an external include. Here's how it looks: <!DOCTYPE html> <html lang="en"> <head> ... </head> <body> ...html code goes here... & ...

Chrome on OSX Mavericks threw a RangeError because the maximum call stack size was exceeded

While attempting to run an Angular app using linemanjs in Chrome on a Mac, I encountered the following error: Uncaught RangeError: Maximum call stack size exceeded An interesting observation is that the site functions properly on Chrome on a Windows mach ...

Steps for building an API to connect to our proprietary database using the WSO2 API manager

Currently, I am looking to share my data from my personal postgresql database by creating an API. In this case, I plan on utilizing the WSO2 API manager for the process. I am uncertain if I am proceeding in the correct manner, so any advice on the differe ...

Incorporate a fresh element into an object after its initial creation

Hello, I am looking to create an object in JavaScript that includes an array-object field called "Cities." Within each city entry, there should be information such as the city's name, ID, key, and a District array object containing town data for that ...

What is the mechanism for invoking functions defined with the arrow syntax in Angular?

Referencing this code snippet from the tutorial at https://angular.io/tutorial/toh-pt4, specifically within the hero.component.ts file: getHeroes(): void { this.heroService.getHeroes() .subscribe(heroes => this.heroes = heroes); } After analyz ...

Prevent Dehydration issue while using context values in Next Js

Every time I log in with a user, update a context value, and re-render some components, I keep encountering a Hydration error in Next Js. The issue seems to be specifically with my NavBar component which is rendered using react-bootstrap. The code snippet ...

Having trouble with blueprintjs icons not appearing as they should on certain pages

I have recently updated an older React application from blueprintjs version 1 to version 4 by following the documentation. However, I am now facing an issue where the icons are not displaying correctly as shown in the image below. Could someone please poi ...

Tips for showcasing overflowing text in a menu list by rotating the item text

Imagine you have a TextMenuItem component, using MenuItem from the Material-UI library, that is part of a chain consisting of DropDownSearch > SimpleListMenu > FixedSizeList > TextMenuItem. In simple terms, this creates a searchable dropdown eleme ...

Error: ReactJs unable to find location

I'm attempting to update the status of the current page when it loads... const navigation = \[ { name: "Dashboard", href: "/dashboard", current: false }, { name: "Team", href: "/dashboard/team", current: fa ...

Creating consistent widths for drop downs and text boxes in Bootstrap

I'm currently using VB.Net MVC, Razor, Bootstrap, and Visual Studio 2013. My clients have requested that the dropdowns match the width of the text boxes. Here is how I create my dropdowns: @<div class="row"> <div class="col-md-4"> ...

Error in JScript encountered during the downgrade to .NET Framework 2.0

Working on a Web Application project has brought about some challenges for me. Originally created in .NET 3.5, I recently found out that it has to be converted to .NET 2.0 (sigh). This transition not only caused issues with the LINQ functionalities but als ...

Retrieve the public URL from the index.html file following the build process

In my project, I utilized ReactJS by creating an app with the command npx create-react-app my-app. To build the project, I used yarn build. Within the package.json file, the scripts section appears as follows: "scripts": { "start": "react-scripts sta ...