0

I was working on a landing video section which has a video playing in the background and according to the video there is some text that will change with respect to the video depending on the video timing. The text animation is using keyframes. I've got it working but I am stuck at a point I.e., delay while looping.

On window load(starting of video) everything works fine but when the video comes to an end and starts back to the loop there is like 1 second or fraction of seconds of delay for the video to restart after the loop. "This is my actual problem" when the video restarts the text changes which is in keyframes delays and has its iteration count set to infinite. The text is not matching with the video the second time. when I stay on that section like for a minute video is not matching with the text slides.

Is there any way to delay the animation with CSS or jQuery that the text delays when video starts looping for the second time.

Here is the Codepen link

Below is the code I am working on.

body {
  background-color: #02001b;
}

.wrapper {
  position: relative;
  width: 1455px;
  height: 799px;
  margin: 0 auto;
}

.header-section section {
  width: 45%;
  height: 200px;
  margin: 0 auto;
  text-align: center;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  overflow: hidden;
}

.as-main-heading {
  color: #fff;
  text-transform: uppercase;
  font-size: 36px;
  font-weight: 300;
}

.as-main-excerpt {
  color: #fff;
  font-size: 18px;
}

.header-section .first,
.header-section .second,
.header-section .third,
.header-section .fourth {
  position: absolute;
  left: 0;
  right: 0;
  animation-duration: 12s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}

.header-section .first {
  animation-name: anim-1;
}

.header-section .second {
  animation-name: anim-2;
}

.header-section .third {
  animation-name: anim-3;
}

.header-section .fourth {
  animation-name: anim-4;
}

@keyframes anim-1 {
  0%,
  8% {
    opacity: 0;
    top: 54%;
  }
  8%,
  16% {
    bottom: 25%;
    top: 54%;
    opacity: 1;
  }
  25%,
  100% {
    bottom: 50%;
    top: 25%;
    opacity: 0;
  }
}

@keyframes anim-2 {
  0%,
  25% {
    opacity: 0;
  }
  32%,
  40% {
    bottom: 25%;
    opacity: 1;
  }
  50%,
  100% {
    bottom: 50%;
    opacity: 0;
  }
}

@keyframes anim-3 {
  0%,
  50% {
    opacity: 0;
  }
  58%,
  66% {
    bottom: 25%;
    opacity: 1;
  }
  75%,
  100% {
    bottom: 50%;
    opacity: 0;
  }
}

@keyframes anim-4 {
  0%,
  75% {
    opacity: 0;
  }
  81%,
  92% {
    bottom: 25%;
    opacity: 1;
  }
  100% {
    bottom: 50%;
    opacity: 0;
  }
}
<div class="wrapper">
  <video autoplay muted loop id="myVideo" height="800px;">
      <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
  </video>
  <div class="landing-header">
    <div class="header-section">
      <section>
        <h2 class="as-main-heading">Story of a bunny</h2>
        <div class="as-main-excerpt first">
          <p>Here comes a butterfly</p>
        </div>
        <div class="as-main-excerpt second">
          <p>Bunny See's the butterfly</p>
        </div>
        <div class="as-main-excerpt third">
          <p>Butterfly Sitting on the flower</p>
        </div>
        <div class="as-main-excerpt fourth">
          <p>An apple falls on the butterfly</p>
        </div>
      </section>

    </div>
  </div>
</div>
Mohammed Wahed Khan
  • 836
  • 2
  • 14
  • 35
  • Have you tried [delaying the loop instead](https://stackoverflow.com/questions/32058967/html5-video-loop-with-a-gap-or-delay-of-few-seconds)? – Adelin Jul 20 '18 at 09:00
  • @Adelin I don't want to delay the loop of the video I want to delay the Keyframes loop for the second time. – Mohammed Wahed Khan Jul 20 '18 at 09:06

2 Answers2

1

You can delay your text animation using animation-delay

.header-section .first,
.header-section .second,
.header-section .third,
.header-section .fourth {
  position: absolute;
  left: 0;
  right: 0;
  animation-duration: 12s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-delay: 1s;
}
Hyyan Abo Fakher
  • 3,497
  • 3
  • 21
  • 35
1

You can achieve it quite simply by restarting your whole animation every time the video starts a new loop.

To detect this event, you can listen for the Media event onplaying.
To restart your animation, you can set a class (e.g .playing) on a parent element which will tell when the animation should be active, and then remove this class and force a reflow so that the browser deactivates the animation, and finally set back the playing class.

var header = document.querySelector('.header-section');
myVideo.onplaying = function(e) {
  header.classList.remove('playing'); // deactivate the animation
  header.offsetWidth; // force a reflow
  header.classList.add('playing'); // reactivate the animation
} 
body {
  background-color: #02001b;
}

.wrapper {
  position: relative;
  width: 1455px;
  height: 799px;
  margin: 0 auto;
}

.header-section section {
  width: 45%;
  height: 200px;
  margin: 0 auto;
  text-align: center;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  overflow: hidden;
}

.as-main-heading {
  color: #fff;
  text-transform: uppercase;
  font-size: 36px;
  font-weight: 300;
}

.as-main-excerpt {
  color: #fff;
  font-size: 18px;
}

.header-section .first,
.header-section .second,
.header-section .third,
.header-section .fourth {
  position: absolute;
  left: 0;
  right: 0;
  animation-duration: 12s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}
/* The animation is set only when the parent has the .playing class */
.header-section.playing .first {
  animation-name: anim-1;
}

.header-section.playing .second {
  animation-name: anim-2;
}

.header-section.playing .third {
  animation-name: anim-3;
}

.header-section.playing .fourth {
  animation-name: anim-4;
}

@keyframes anim-1 {
  0%,
  8% {
    opacity: 0;
    top: 54%;
  }
  8%,
  16% {
    bottom: 25%;
    top: 54%;
    opacity: 1;
  }
  25%,
  100% {
    bottom: 50%;
    top: 25%;
    opacity: 0;
  }
}

@keyframes anim-2 {
  0%,
  25% {
    opacity: 0;
  }
  32%,
  40% {
    bottom: 25%;
    opacity: 1;
  }
  50%,
  100% {
    bottom: 50%;
    opacity: 0;
  }
}

@keyframes anim-3 {
  0%,
  50% {
    opacity: 0;
  }
  58%,
  66% {
    bottom: 25%;
    opacity: 1;
  }
  75%,
  100% {
    bottom: 50%;
    opacity: 0;
  }
}

@keyframes anim-4 {
  0%,
  75% {
    opacity: 0;
  }
  81%,
  92% {
    bottom: 25%;
    opacity: 1;
  }
  100% {
    bottom: 50%;
    opacity: 0;
  }
}
<div class="wrapper">
  <video autoplay muted loop id="myVideo" height="800px;">
      <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
  </video>
  <div class="landing-header">
    <div class="header-section">
      <section>
        <h2 class="as-main-heading">Story of a bunny</h2>
        <div class="as-main-excerpt first">
          <p>Here comes a butterfly</p>
        </div>
        <div class="as-main-excerpt second">
          <p>Bunny See's the butterfly</p>
        </div>
        <div class="as-main-excerpt third">
          <p>Butterfly Sitting on the flower</p>
        </div>
        <div class="as-main-excerpt fourth">
          <p>An apple falls on the butterfly</p>
        </div>
      </section>

    </div>
  </div>
</div>

Regarding the comment that changes everything (i.e you need to have a pause and play feature), then the best is probably to get rid of the CSS animations altogether, and to control your elements all from js (helped by CSS transitions):

var header = document.querySelector('.header-section');
var chapters = [0, 0.96, 1.92, 2.9, 4.2, 5.4, 6.5, 7.2, 9, 11];
var classes = ['', 'first-in', 'first-out', 'second-in', 'second-out', 'third-in', 'third-out', 'fourth-in', 'fourth-out', ''];

var currentFrame = 0;
myVideo.ontimeupdate = function() {
  var nextFrame = (currentFrame + 1) % chapters.length;
  if(myVideo.currentTime >= chapters[nextFrame] || myVideo.currentTime < chapters[currentFrame]) {
//    if(classes[currentFrame]) header.classList.remove(classes[currentFrame]);
    if(classes[nextFrame]) header.classList.add(classes[nextFrame]);
    currentFrame = nextFrame;
    if(!nextFrame) // did loop
      classes.forEach(remove);
    header.offsetTop;
  }

};
function remove(classname) {
  if(classname)header.classList.remove(classname);
}

onclick = function(e) {
  if(myVideo.paused) myVideo.play();
  else myVideo.pause();
}
body {
  background-color: #02001b;
}

.wrapper {
  position: relative;
  width: 1455px;
  height: 799px;
  margin: 0 auto;
}

.header-section section {
  width: 45%;
  height: 200px;
  margin: 0 auto;
  text-align: center;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  overflow: hidden;
}

.as-main-heading {
  color: #fff;
  text-transform: uppercase;
  font-size: 36px;
  font-weight: 300;
}

.as-main-excerpt {
  color: #fff;
  font-size: 18px;
}

.header-section .as-main-excerpt {
    position: absolute;
    left: 0;
    right: 0;
    opacity: 0;
    top: 54%;
    transition-property: opacity bottom top;
    transition-duration: 1s;
    transition-timing-function: ease-in-out;
    
}

.header-section.first-in .first,
  .header-section.second-in .second,
  .header-section.third-in .third,
  .header-section.fourth-in .fourth {
    bottom: 25%;
    top: 54%;
    opacity: 1;
}
.header-section.first-out .first,
  .header-section.second-out .second,
  .header-section.third-out .third,
  .header-section.fourth-out .fourth {
    bottom: 50%;
    top: 25%;
    opacity: 0;
}
video {
  pointer-events: none;
}
<div class="wrapper">
  <video autoplay muted loop id="myVideo" height="800px;">
      <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4">
  </video>
  <div class="landing-header">
    <div class="header-section playing">
      <section>
        <h2 class="as-main-heading">Story of a bunny</h2>
        <div class="as-main-excerpt first">
          <p>Here comes a butterfly</p>
        </div>
        <div class="as-main-excerpt second">
          <p>Bunny See's the butterfly</p>
        </div>
        <div class="as-main-excerpt third">
          <p>Butterfly Sitting on the flower</p>
        </div>
        <div class="as-main-excerpt fourth">
          <p>An apple falls on the butterfly</p>
        </div>
      </section>

    </div>
  </div>
</div>
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • I forgot to mention in the question, I got a play and pause functionality on the video, that is if I click anywhere on the video the video should pause and play. I got my video loop working with your help but I want those text changing keyframes to stop on click too. Would that be possible? Here is an updated [codepen](https://codepen.io/Wahed98666/pen/wxoRQE) – Mohammed Wahed Khan Jul 23 '18 at 10:52
  • You saved my day that is working, exactly what I wanted to achieve. Thanks man. – Mohammed Wahed Khan Jul 24 '18 at 04:57