After each animation in the sequence is completed, CSS3 looping occurs

I have currently set up a sequence of 5 frames, where each frame consists of 3 animations that gradually fade into the next frame over time.

My challenge is figuring out how to loop the animation after completing the last sequence (in this case, #frame2).

I am open to using JavaScript to potentially detect and "force" the loop.

View the Fiddle here: http://jsfiddle.net/a0cpo5xe/1/ - The setup includes 5 frames:

#frame1 {
    animation:kf_frame_fade_up 0.4s;
    animation-fill-mode: forwards;
    animation-delay:0.8s;
}

#picture-1 .blink {
    animation:kf_frame_fade_down 0.2s;
    animation-fill-mode: forwards;
    animation-delay:0.5s;
}
#picture-1 .picture {
    animation:kf_frame_fade_up 0.2s;
    animation-fill-mode: forwards;
    animation-delay:0.5s;
}

#frame2 {
    animation:kf_frame_fade_up 0.4s;
    animation-fill-mode: forwards;
    animation-delay:4.3s;
}

#picture-2 .blink {
    animation:kf_frame_fade_down 0.2s;
    animation-fill-mode: forwards;
    animation-delay:4s;
}
#picture-2 .picture {
    animation:kf_frame_fade_up 0.2s;
    animation-fill-mode: forwards;
    animation-delay:4s;
}

/* FADES */
@keyframes kf_frame_fade_up {
    0% {opacity: 0;}
    100% {opacity: 1;}
}

@keyframes kf_frame_fade_down {
    0% {opacity: 1;}
    100% {opacity: 0;}
}

Answer №1

To determine if the animation has ended, you can use JavaScript to listen for the animationend event.

animationend

The animationend event is triggered when a CSS animation is completed.

Here's an example of repeating your CSS animation from your JSFiddle three times by cloning the elements, removing them, and then adding them back at the end of the animation.

I'm confident you'll grasp the concept quickly.

var i = 1;

function whichAnimationEvent(){
  var t,
      el = document.createElement("fakeelement"),
      animations = {
        "animation"      : "animationend",
        "WebkitAnimation": "webkitAnimationEnd"
      };

  for (t in animations){
    if (el.style[t] !== undefined){
      return animations[t];
    }
  }
}

function init() {
  var animationEvent = whichAnimationEvent(),
      wrp = document.getElementById('wrapper'),
      frm2 = document.getElementById('frame2');
      cln = wrp.cloneNode(true);

  function animationEnd(evt) {
    i++;
    //console.log(evt);
    wrp.parentNode.removeChild(wrp);
    document.body.appendChild(cln);
    if (i !== 3) {
      init();
    }

  }

  frm2.addEventListener(animationEvent, animationEnd);
}

init();
#wrapper {
  text-align: center;
  color: #ffffff;
}

#frames {
  position: absolute;
  left: 0;
  top: 0;
  width: 200px;
  height: 200px;
  border: 1px solid #000000;
}

.frame {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;

  opacity: 0; /* hide */
}

#pictures {
  position: absolute;
  top: 0;
}

.picture {
  position: absolute;
  top: 100px;
  left: 100px;
  padding: 10px;
  opacity: 0; /* hide */
}

/* ANIMATION START */
#frame1 {
  background-color: green;
  -webkit-animation:kf_frame_fade_up 0.4s;
  animation:kf_frame_fade_up 0.4s;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-delay:0.8s;
  animation-delay:0.8s;
}

#picture-1 .picture {
  background-color: #116343;
  -webkit-animation:kf_frame_fade_up 0.2s;
  animation:kf_frame_fade_up 0.2s;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-delay:0.5s;
  animation-delay:0.5s;
}

#frame2 {
  background-color: blue;
  -webkit-animation:kf_frame_fade_up 0.4s;
  animation:kf_frame_fade_up 0.4s;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-delay:4s;
  animation-delay:4s;
}

#picture-2 .picture {
  background-color: #3d1163;
  -webkit-animation:kf_frame_fade_up 0.2s;
  animation:kf_frame_fade_up 0.2s;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  -webkit-animation-delay:3.7s;
  animation-delay:3.7s;
}

/* FADES */
@-webkit-keyframes kf_frame_fade_up {
  0% {opacity: 0;}
  100% {opacity: 1;}
}
@keyframes kf_frame_fade_up {
  0% {opacity: 0;}
  100% {opacity: 1;}
}

@-webkit-keyframes kf_frame_fade_down {
  0% {opacity: 1;}
  100% {opacity: 0;}
}

@keyframes kf_frame_fade_down {
  0% {opacity: 1;}
  100% {opacity: 0;}
}
<div id="wrapper">
  <div id="frames">
    <div id="frame1" class="frame">frame 1</div>
    <div id="frame2" class="frame">frame 2</div>
  </div>
  <div id="pictures">
    <div id="picture-1">
      <div class="picture">pic 1</div>
    </div>
    <div id="picture-2">
      <div class="picture">pic 2</div>
    </div>
  </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

The value of the bound variable in ng-options does not get updated after the array is

I have a situation where I am populating a list using an array and the ng-options directive in AngularJS. The selected item is bound to a variable called myObject.selectedItem. However, I noticed that even after clearing the array, the value of myObject.se ...

Looking to duplicate the elements with the click of a button?

I am in need of assistance with my registration form. My goal is to move the elements contained within the <fieldset> tags to the end of a row when the user clicks the + button. The result you see initially has been recreated. Thank you for your s ...

JavaScript not functional post AJAX request - navigating AJAX tabs

I am attempting to create a submenu that can update the page content without refreshing by using AJAX tabs to call an external HTML file. While the tabs are functioning properly, I am facing an issue with a JavaScript code within the external HTML file tha ...

Angular 6: A guide to dynamically highlighting navbar elements based on scroll position

I am currently building a single page using Angular 6. The page is quite basic, and my goal is to emphasize the navbar based on scrolling. Below is the code snippet I am working with: .sticky { position: sticky; top: 0; } #i ul { list-style-type: ...

Error: The promise was not caught due to a network issue, resulting in a creation error

I'm trying to use Axios for API communication and I keep encountering this error. Despite researching online and attempting various solutions, I am still unable to resolve the problem. Can someone please assist me? All I want is to be able to click on ...

What is the best way to verify multiple email addresses simultaneously?

Is there a method to validate multiple email addresses entered by users in a textarea? My current approach involves using ng-pattern for validation. ...

An operator in rxjs that transforms an Observable of lists containing type X into an Observable of type X

Currently, I am facing a challenge while dealing with an API that is not very user-friendly using Angular HTTP and rxjs. My goal is to retrieve an Observable<List<Object>> from my service. Here's a snippet of the JSON output obtained from ...

In-line divs are known for their rebellious nature, refusing to conform to traditional

I'm in need of some assistance with taming my unruly HTML. It seems to be misbehaving lately. The content area on the page I'm currently designing has a two-column layout. Instead of using separate containing divs for each column, I opted for a ...

How can I style the inner div by adding a class to the first div?

In my project, I have a list of elements that are generated dynamically, all styled the same way but with different content. The first element has a specific styling, and if it doesn't render, I want the second element to inherit that styling. < ...

Creating regex to detect the presence of Donorbox EmbedForm in a web page

I am working on creating a Regex rule to validate if a value matches a Donorbox Embed Form. This validation is important to confirm that the user input codes are indeed from Donorbox. Here is an example of a Donorbox EmbedForm: <script src="https: ...

Angular 2, React, or any other modern framework.getList()?.map

I have experience working on multiple angular 1 projects and I absolutely enjoyed it. We have several upcoming projects where I need to recommend JavaScript frontend libraries/frameworks. With the decline of angular 1 and mixed reviews about angular 2&apos ...

Reactjs - There was an error: $node.attr(...).tooltip is not defined

I am currently troubleshooting the SummerNote mention library and encountering an issue - Uncaught TypeError: $node.attr(...).tooltip is not a function The versions I am using are: - "react-summernote": "^2.0.0", - React version: "react": "^16.8.6", ...

Javascript code not running as expected

Check out this code snippet: function generateRandomTeams() { const prom = new Promise(() => { // ... console.log('teams', props.state.teams) // logs }) .then(() => { console.log('here') // doesn't log }) ...

Error: 'error' is undefined

Error Alert: The code is encountering a ReferenceError, indicating that 'error' is not defined in the following snippet: app.post('/register', function(req, res) { var hash = bcrypt.hashSync(req.body.password, bcrypt.genSaltSync(10)) ...

Load data from a file into a dropdown menu using node.js

Exploring the realm of front end development on my own has been quite a challenge. I am currently struggling with the concept of populating a drop down box with data from a file. While utilizing node and JavaScript, I have decided to stick to these techn ...

"Customizing the topbar of Twitter Bootstrap for right-to

Attempting to implement twitter bootstrap for a top navigation bar on my master page. http://jsfiddle.net/ZqCah/1/ Encountering some issues and seeking assistance: 1- Desiring to switch the direction of all content to right-to-left (rtl). This would me ...

Leaving the "OK" button untouched in the sweet alert dialog

While implementing sweet alert in my project, I encountered an issue where the button text was not changing and the cancel button was missing on some pages. On certain pages, it only displayed OK. You can see a screenshot below for reference. https://i.s ...

React - Unable to perform 'removeChild' on 'Node' object: The specified node cannot be removed as it is not a child of this node

I am encountering an issue in my React project with the following structure: <div className="App"> <BrowserRouter> <BasicLayout title={"test"}> <Routes> <Route path="/home&qu ...

if statement not recognizing data returned from PHP function

I'm currently working with a function that is being used for an AJAX query: var formData = $(this).serialize(); //store form names and values in an array called 'formData' $.get('filtertest.php',formData,processData); //jQ ...

Steps to integrate the Save as PNG functionality in Vega using a customized menu

As I develop a data dashboard with Vega for visualizing outputs, I decided to customize the menu system by removing the actions dropdown. However, I still want to incorporate the "Save as PNG" option from the original dropdown (as shown in the image below) ...