Stop the CSS animation on the circular menu to toggle it open and closed

I have a circular menu with the added code "animation: pulse infinite". The menu can be opened and dragged around.

Now, I want to add a pause animation so that it stops for a while when the menu is opened and closed.

I tried adding "animation-play-state" and setting it to "paused", but then the animation does not resume after closing the menu.

Can someone help me figure out how to make the animation resume?

Here is my code:

@import url("https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css");
@import "compass/css3";
body {
  background: #fff;
  height: 100%;
}

.circular-menu {
  width: 250px;
  height: 250px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
}

.circle {
  width: 250px;
  height: 250px;
  opacity: 0;
  -webkit-transform: scale(0);
  -moz-transform: scale(0);
  transform: scale(0);
  -webkit-transition: all 0.4s ease-out;
  -moz-transition: all 0.4s ease-out;
  transition: all 0.4s ease-out;
}

.open.circle {
  opacity: 1;
  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  transform: scale(1);
}

.circle a {
  z-index: auto;
  text-decoration: none;
  color: #0081ee;
  display: block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  margin-left: -20px;
  margin-top: -20px;
  position: absolute;
  text-align: center;
}

...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<body>
  <nav class="circular-menu" id="draggable">
    <div class="circle">
      <!-- save the script -->
      ...
    </div>
    <div id="pulsing" onclick="myFunction()">
      <a href="" class="menu-button fa fa-bars fa-2x" id="pulsing"></a>
    </div>
  </nav>
</body>

Or check it out here.

Answer №1

Instead of always adding style for pausing the animation, consider toggling it on and off. Just like you would for opening and closing a menu.

In the snippet provided, all I did was move the animation-state: paused to a CSS class called .paused, and then toggle this class on click.

var items = document.querySelectorAll(".circle a");

for (var i = 0, l = items.length; i < l; i++) {
items[i].style.left = (50 - 35 * Math.cos(-0.5 * Math.PI - 2 * (1 / l) * i * Math.PI)).toFixed(4) + "%";

items[i].style.top = (50 + 35 * Math.sin(-0.5 * Math.PI - 2 * (1 / l) * i * Math.PI)).toFixed(4) + "%";
}

let onClickHandler = function (e) {
e.preventDefault();
document.querySelector(".circle").classList.toggle("open");
  document.querySelector(".menu-button").classList.toggle("paused");
    };

document.querySelector(".menu-button").onclick = onClickHandler;

let tooltipElem;
document.onmouseover = function (event) {
let target = event.target;
let tooltipHtml = target.dataset.tooltip;
if (!tooltipHtml) return;
tooltipElem = document.createElement("div");
tooltipElem.className = "tooltip";
tooltipElem.innerHTML = tooltipHtml;
document.body.append(tooltipElem);
let coords = target.getBoundingClientRect();
let left = coords.left + (target.offsetWidth - tooltipElem.offsetWidth) / 2;
if (left < 0) left = 0;
let top = coords.top - tooltipElem.offsetHeight - 5;
if (top < 0) {
top = coords.top + target.offsetHeight + 5;
}
tooltipElem.style.left = left + "px";
tooltipElem.style.top = top + "px";
};

document.onmouseout = function (e) {
if (tooltipElem) {
tooltipElem.remove();
tooltipElem = null;
}
};

function setOnClickHandler() {
document.querySelector(".menu-button").onclick = onClickHandler;
}

$(document).ready(function () {
$("#draggable").draggable({
start: function( event, ui ) {
document.querySelector(".menu-button").onclick = null;
},
stop: function( event, ui ) {
document.querySelector(".menu-button").onclick =
setTimeout(setOnClickHandler, 0);
}
});
});
@import url("https://netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css");
@import "compass/css3";

body {
  background: #fff;
  height: 100%;
}

.circular-menu {
  width: 250px;
  height: 250px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
}

.circle {
  width: 250px;
  height: 250px;
  opacity: 0;
  -webkit-transform: scale(0);
  -moz-transform: scale(0);
  transform: scale(0);
  -webkit-transition: all 0.4s ease-out;
  -moz-transition: all 0.4s ease-out;
  transition: all 0.4s ease-out;
}

.open.circle {
  opacity: 1;
  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  transform: scale(1); 
}

.circle a {
  z-index: auto;
  text-decoration: none;
  color: #0081ee;
  display: block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  margin-left: -20px;
  margin-top: -20px;
  position: absolute;
  text-align: center;
}

.tooltip {
  position: fixed;
  padding: 10px 20px;
  border: 1px solid #b3c9ce;
  border-radius: 4px;
  text-align: center;
  font: 14px/1.3 sans-serif;
  color: #333;
  background: #fff;
  box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.3);
  z-index: 2;
}

.circle a:hover {
  color: #0081ee;
}

.menu-button {
  position: absolute;
  top: calc(50% - 30px);
  left: calc(50% - 30px);
  text-decoration: none;
  text-align: center;
  color: #fff;
  border-radius: 50%;
  border: none;
  display: inline-block;
  height: 40px;
  width: 40px;
  line-height: 40px;
  padding: 10px;
  background: #0081ee;
  box-shadow: 0 0 0 0 rgba(#0081ee, .5);
  z-index: 1;
  animation: pulse 1.5s infinite;
}

.menu-button:hover, .menu-button.paused {
  animation-play-state: paused;
}

@keyframes pulse {
  0% {
    transform: scale(.9);
  }
  70% {
    transform: scale(1.1);
    box-shadow: 0 0 0 40px rgba(#0081ee, 0);
    
  }
  100% {
    transform: scale(.9);
    box-shadow: 0 0 0 0 rgba(#0081ee, 0);
  }
}

.pulsing
{
  width: 100%;
  height: 100%;
  margin: 0 auto 0;
  perspective: 1000;
  backface-visibility: hidden;
  background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<body>
<nav class="circular-menu" id="draggable">
  <div class="circle">
    <!-- save the script -->
    <a href="" class="fa fa-check fa-2x" data-tooltip="сохранить текущий сценарий"></a>
    <!-- delete a step -->
    <a href="" class="fa fa-trash fa-2x" data-tooltip="удалить шаг"></a>
    <!-- add a step -->
    <a href="" class="fa fa-plus fa-2x" data-tooltip="добавить шаг"></a>
    <!-- cancel the creation of script -->
    <a href="" class="fa fa-window-close fa-2x" data-tooltip="отменить создание сценария"></a>
    <!-- переход на другой сайт, не знаю, подходит ли иконка -->
    <a href="" class="fa fa-internet-explorer fa-2x" data-tooltip="перейти на другую страницу или сайт"></a>
  </div>
  <div id="pulsing">
  <a href="" class="menu-button fa fa-bars fa-2x" id = "pulsing"></a>
    </div>
</nav>
  </body>

Answer №2

In order to revert CSS properties back to normal after JavaScript(JQuery) has overridden them, you must use JavaScript to make the changes.
Modify your function like so:

let onClickHandler = function (e) {
  e.preventDefault();
  var a = document.querySelector(".circle");
  document.querySelector(".circle").classList.toggle("open");
  if(a.className == "circle open")
    $(".menu-button").css("animation-play-state", "paused");
  else
    $(".menu-button").css("animation-play-state", "running");
};

Because I am unfamiliar with JQuery, I handled everything using JavaScript instead.

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

Most effective method for showcasing the image once it has been successfully loaded

At the moment, I am considering two methods to display an image after it has been loaded. Initial Method <img id="myImage" /> var img = new Image(), x = document.getElementById("myImage"); img.onload = function() { x.src = img.src; }; img ...

What is the reasoning behind CoffeeScript automatically adding a function when extending an Object?

I'm currently working on a helper method to identify the intersection of two hashes/Objects in this manner... Object::intersect = (obj)-> t = {} t[k] = @[k] for k of obj t x = { a: 1, b: 2, c: 3 } w = { a: true, b: 3 } x.intersect(w) #=> ...

Struggling to incorporate a radio button into my table design, despite attempting various CSS adjustments without success

After adding a radio button element to my table, I noticed it was not appearing on the page. To troubleshoot, I created a snippet with the same code and found that the radio button did show up there. Additionally, when I added a background color to see whe ...

Utilizing jQuery for altering the navigation color is yielding inconsistent outcomes

I developed a snippet of jQuery script that dynamically adjusts the color of my navigation/header depending on the section of my website that the user is viewing. Although it functions, there are some imperfections. At times, it changes colors in the middl ...

adjusting the length of the right boundary

I am looking to customize the size of the right border on each tab within my menu, or have the borders extend the entire vertical length of the menu. View my current code snippet here: http://jsfiddle.net/5FP8R/ <div id="menu"> <ul> ...

Add HTML and JavaScript code dynamically with JavaScript

Currently, I am working on a project that involves an HTML table with some basic JS interactions triggered by user clicks. The structure looks something like this: htmlfile.html ... ... position action ...

How come I am unable to track the total number of uploaded images while fetching them?

Within my vuejs2 app, I am facing an issue with uploading images selected in a modal form. The goal is to close the modal form only after all images have been successfully saved, triggering the self.hidePhotosUploadingModal() method. To keep track of the ...

Error message received when calling a function within a Vue watcher states "function is not defined"

My goal is to trigger a function in a Vue component when a prop changes using a watcher: props: [ 'mediaUrl' ], watch: { mediaUrl: function() { this.attemptToLoadImage(); } }, medthods: { attemptToLoadImage: function() { console ...

Having trouble updating textures when clicking a button in Aframe

I'm attempting to load a gltf model and change the texture on button click using the register component. The model loads and displays as expected, but I'm having trouble reflecting any changes when the button is clicked for the texture change. H ...

Connect different CSS variables within a related context

Looking to incorporate Font Awesome 5.10.2 Duotone icons easily into any HTML element. The icon element relies on HTML attributes that should correspond to a specific icon, with the mapping controlled by the CSS author. <x pay></x> <!-- Th ...

What is the best way to accurately determine the height and offset values of an element while utilizing ng-repeat?

My objective is to determine the offset and height of list items. Once I have those values, I trigger a function in a parent directive. Ultimately, this will involve transitioning elements in and out as they come into view. Issue: Due to the use of ng-rep ...

Verification response parameter not received from Google Authentication Express

I've been working on implementing a "sign in with Google" feature for my localhost website. Despite receiving the POST request, I noticed that it lacks the credential parameter. I'm unsure if this issue lies within the code or the API configurati ...

Problem with JQuery binding

Currently, I have set up my radio buttons with jQuery bind using the code below: jQuery().ready(function() { jQuery("input[name='rank_number']:radio").bind('change', function(){ submitSelectedRank(); }); }); While th ...

Toggle the visibility of a div using JavaScript depending on the data value

I have a collection of images displayed in div tags with data attributes. My goal is to toggle their visibility using CSS based on a match with input text. I iterate through the divs with the matching class, then loop through the words in the input array, ...

Updating objects in Angular 8 while excluding the current index: a guide

this.DynamicData = { "items": [ { "item": "example", "description": "example" }, { "item": "aa", "description": "bb" }, ...

Content in Bootstrap not filling entire mobile screen

The content in this form does not stretch to full screen on mobile phones, but it appears properly on computers and tablets. Please advise on how to solve this issue. https://i.stack.imgur.com/S2XkS.jpg <link rel="stylesheet" href="https://maxcdn.bo ...

Revamping the personalized mini-cart in Woocommerce using ajax for a fresh look

I've been working on creating a user-friendly interface in Woocommerce that allows a product to be added directly to the mini cart next to it using AJAX, instead of having the page refresh every time an item is added to the cart. However, I'm fac ...

Converting counterup2 to pure vanilla JavaScript: step-by-step guide

Is there a way to convert the counterUp2 jQuery code to vanilla JavaScript? const counters = document.querySelectorAll('.counter'); function count(element) { let currentValue = 0; const targetValue = parseInt(element.innerText); let interv ...

There is an error occurring in Angular 9 when trying to implement a search filter for an object array with heterogeneous types

Trying to search through an array of objects using key-value pairs, but encountering an error in the console: core.js:5873 ERROR TypeError: obj[key].includes is not a function a = [ { id: 0, name: "xyz", grade: "x", frade: [ { name: "Paul", ...

What is the best way to incorporate a horizontal scroll bar at the top of a table?

<div class="table-responsive"> <table class="table table-striped"> <thead> <tr> <th> ...