"Mastering the art of patience: Delaying execution until an animation completes using

When attempting to create an infinite loop for a carousel with a click event on a specific div to center it at a desired position, I encountered an issue. If the clicked item is more than one position away from the center, an unexpected effect occurs that does not follow the usual logic.

I attempted to address this problem by calculating the distance from the center and moving the items one by one accordingly. However, due to the asynchronous nature of animations, the loop doesn't wait for the animations to finish, resulting in the strange effect.

The desired outcome is to achieve an infinite carousel feel where clicking an item five positions away from the center centers it, causing the out-of-view items to slide in from their respective directions to create a loop effect.

Any assistance would be greatly appreciated as I am new to web development. A well-explained solution would be highly valued.

JS:

const serviceList = document.querySelectorAll('.service__block');

serviceList.forEach(service => {
  service.addEventListener('click', () => {
    markSelectedService(service);
    moveService(checkDistance(service));
  });
});

//Adds the class to the clicked service
function markSelectedService(service) {
  removeSelectedClass();
  service.classList.add('selected');
}

//Removes the selected class from all services
function removeSelectedClass() {
  serviceList.forEach(service => {
    service.classList.remove('selected');
  });
}

//Check distance from center
function checkDistance(service) {
  let distance = service.dataset.order - 4;
  return distance;
}

//Move the service one by one n times
function moveService(distance) {
  if (distance > 0) {
    for (var i = 0; i < distance; i++) {
      serviceList.forEach(service => {
        service.dataset.order = parseInt(service.dataset.order) - 1;
        if (parseInt(service.dataset.order) === -1) {
          service.dataset.order = 11;
        }
      });
    }
  } else if (distance < 0) {
    distance = distance * -1;
    for (var i = 0; i < distance; i++) {
      serviceList.forEach(service => {
        service.dataset.order = parseInt(service.dataset.order) + 1;
        if (parseInt(service.dataset.order) === 12) {
          service.dataset.order = 0;
        }
      });
    }
  }
}

Link to codepen: https://codepen.io/tomyshoam/pen/yLLLYyQ

Answer №1

To ensure that the next animation is triggered only after the current one has ended, you can use a setInterval function and set the interval time to match your animation's duration. Here's an example:

var i = 0;
var animationInterval = setInterval(function () {

   //YOUR LOGIC HERE

   if (++i === distance) {
     window.clearInterval(animationInterval);
   }
}, 500);

Update

After experimenting with different approaches, I believe I have achieved the desired outcome, although it may not be the most efficient method. I duplicated the list of icons, placing one on the right side and one on the left. This ensures that the icons will only transition to the other side when they are sufficiently far from the user's view, avoiding any unexpected behavior.

View the code here: https://codepen.io/diogoperes/pen/oNNNBGY

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

Reduce the size of several JavaScript files using webpack

Hello, I am a beginner with webpack and I am looking to minify all the files in a folder into a single js file using webpack. I want to avoid adding each file manually in the entry section. I believe there must be a more efficient way to achieve this, bu ...

Locating an inadequately labeled variable or object

Dealing with approximately 100 files written in Python, JavaScript, and HTML has presented me with a challenging task. Many of these files are interconnected in intricate ways, making it difficult for me to trace back the origin of variables or objects. I ...

Java - Changing Font Size in HTML JTextPane with CSS Styling

When utilizing the following code snippet: Action sizeAction = new StyledEditorKit.FontSizeAction(String.valueOf(size), size); The button associated with the action adds the HTML tags: <FONT SIZE="5"> My text here </FONT> Utilizing these ta ...

"Utilizing the useHistory() hook outside of a functional component in React JS: a step-by-step

In my project, I have implemented a function in a separate JavaScript file that is responsible for checking status codes received from API requests. Depending on the code returned, this function needs to execute specific actions: function ...

Refining keys within an array of objects

If I have an array of objects retrieved from a Node Repository like this: data = [ { title: "JavaScript Basics", author: "John Smith", year: 2020 }, { title: "Node.js Essentials", ...

Modify the appearance of a span element when an input is in focus

I am trying to display the word "test" by focusing on a text input. However, when the text input is focused, the z-index of the text should change to 0 but it's not working as expected. I have provided my code below: .text{ position: absolute; ...

Positioning text too far to the left causes it to become disorganized and difficult

I am looking to achieve the following result: LEFT THING, not fixed here comes a text that spans 100% width of this "column" width (content itself but my issue is that when it gets too long, this column drops below determines that) the left ...

Can you make a vertical line that remains a constant size even when the window is resized?

Can someone help me with this? I'm not sure if I'm using the right values for top, left, and bottom. Here's an example below: div.line { width:4px; background-color: black; position: fixed; top:180px; bottom:400px; ...

When using React Ant Design, the form.resetFields() function does not trigger the onChange event of the Form.Items component

In my project, I am working with the Ant Design <Form> component and handling onChange events within <Form.Items>. Whenever the onChange event function evaluates to true, additional content is displayed dynamically. For instance, in the code s ...

Getting data from a PHP request using AngularJS can be achieved by creating an HTTP request in

I am trying to send a basic REST service request using Angular for the PHP code below. Unfortunately, the request is resulting in an error. Check out the live code here PHP Code <?php /* Simple array */ $json = array("status" => 0, "msg" => ...

At initial glance on iOS, the login page remains hidden, but as I tilt the phone, the page fields slowly start to appear

Encountering a strange issue when accessing my application on iOS 11. Initially, the page fails to load completely with missing background and field labels. However, I am able to click on objects. Oddly enough, if I tilt my iPhone or zoom in, the page load ...

What is the process for displaying the save file dialog in Safari?

I'm struggling with generating a PDF and saving it as a file in Safari using an Angular app and DocRaptor. I've tried various methods from Stack Overflow, but none seem to trigger the save file dialog. Instead, they either open the file in the cu ...

Issue with CanvasJS Carousel compatibility on Bootstrap 4 platform

I am struggling to display charts with a carousel feature using CanvasJS. Despite my efforts, I am unable to see any graphs on the page. My framework is Bootstrap 4.1.3. In my attempts to achieve this functionality, I previously experimented with Google C ...

Having difficulty arranging two <p> or <div> elements in a stacked position within the footer

https://i.sstatic.net/7MTbK.png I've been experimenting with different methods to stack the smaller "test" text under the bigger TestTest. It seems to work fine on the rest of the page when I use a separate div, but for some reason, it's not wor ...

Creating a structure within a stencil web component

In my current project, I am utilizing Stencil.js (typescript) and need to integrate this selectbox. Below is the code snippet: import { Component, h, JSX, Prop, Element } from '@stencil/core'; import Selectr from 'mobius1-selectr'; @ ...

Local storage synchronization in progress, please hold on

Currently, there seems to be a synchronization issue between the local storage and the server. Countries, cities, and users are synchronized with the server separately through different Ajax calls. The problem at hand is that other JavaScript codes (such ...

Is there a way to load the right amount of images in advance, depending on the size of the

I'm currently trying to optimize the loading of Largest Contentful Paint (LCP) candidate images based on device size, but I'm encountering difficulties. The issue at hand: On smaller screens, only one image is displayed in a carousel On larger ...

Perform an operation in JQuery after a different operation has been completed

Recently, I came across this JavaScript function that displays a loading image for a few seconds before revealing a hidden div: <script type="text/javascript> $(document).ready(function () { $('#load').html('<img style="display ...

Attempting to format a number using a computed property and .toLocaleString() fails to execute

I am facing an issue with the formatting of a number displayed in a <p></p> element. The number is coming from a range input element that is bound to an amount data property using v-model. Even though I have a computed property to format the nu ...

Utilizing HighCharts in Your Project

View the graph here $(function () { var chart; $(document).ready(function() { chart = new Highcharts.Chart({ chart: { renderTo: 'container', type: 'column', margin: [ 50, 50, 100, 80] ...