Fullscreen Bootstrap 4 carousel Ken Burns and fade

Viewed 1195

My goal is to create a zoom in "Ken Burns" effect and a crossfade transition between slides using Bootstrap 4 carousel. The zooming effect should take 6 seconds and the fading transition 1 second. Also the carousel should loop without being noticed when the transition is made from last and first slide.

The zoom effect works pretty good but it has a "jump" in my demo and the fading transition is not working properly and. I would appreciate help with it. Thanks!

Demo

http://jsfiddle.net/beuL5dcp/

HTML

<div class="carousel slide carousel-fade" data-ride="carousel" data-interval="6000">

    <!--======= Wrapper for Slides =======-->
    <div class="carousel-inner">

            <!--========= First Slide =========-->
            <div class="carousel-item active" style="background-image: url('https://i.picsum.photos/id/878/1920/1680.jpg?hmac=_FQShv6E5HdjI6OKgjozFJQz8SXlT1OwmqijW5jHGQo')">
            </div>

            <!--========= Second Slide =========-->
            <div class="carousel-item" style="background-image: url('https://i.picsum.photos/id/874/1920/1680.jpg?hmac=KDczwg-ejraLUmoflMNUBCkt1LyLxNreJptc7RQajFY')">
            </div>

            <!--========= Third Slide =========-->
            <div class="carousel-item" style="background-image: url('https://i.picsum.photos/id/870/1920/1680.jpg?hmac=IAkVJX2zYS6BuaMLixYh5xoyOpeDH5WkcGTacBUPPXM')">
            </div>

     </div>

 </div>

CSS

.carousel-inner>.carousel-item
{
  margin:auto;
  height: 100vh;
  width:100%;
  -webkit-transform-origin:50% 50%;
  -moz-transform-origin:50% 50%;
  -ms-transform-origin:50% 50%;
  -o-transform-origin:50% 50%;
  transform-origin:50% 50%;
  -webkit-animation:kenburns 6000ms linear 0s infinite;
  animation:kenburns 6000ms linear 0s infinite
}
@-webkit-keyframes kenburns
{
  0%
  {
    -webkit-transform:scale(1);
    -webkit-transition:-webkit-transform 6000ms linear 0s
  }
  100%
  {
    -webkit-transform:scale(1.1);
    -webkit-transition:-webkit-transform 6000ms linear 0s
  }

}
@-moz-keyframes kenburns
{
  0%
  {
    -moz-transform:scale(1);
    -moz-transition:-moz-transform 6000ms linear 0s
  }
  100%
  {
    -moz-transform:scale(1.1);
    -moz-transition:-moz-transform 7000ms linear 0s
  }

}
@-ms-keyframes kenburns
{
  0%
  {
    -ms-transform:scale(1);
    -ms-transition:-ms-transform 6000ms linear 0s
  }
  100%
  {
    -ms-transform:scale(1.1);
    -ms-transition:-ms-transform 6000ms linear 0s
  }

}
@-o-keyframes kenburns
{
  0%
  {
    -o-transform:scale(1);
    -o-transition:-o-transform 6000ms linear 0s
  }
  100%
  {
    -o-transform:scale(1.1);
    -o-transition:-o-transform 6000ms linear 0s
  }

}
@keyframes kenburns
{
  0%
  {
    transform:scale(1);
    transition:transform 6000ms linear 0s
  }
  100%
  {
    transform:scale(1.1);
    transition:transform 6000ms linear 0s
  }

}
3 Answers

The problem with the 'jump' is not because of the @keyframes prefixes but because of the wrong timing. For some reason, the zoom animation is quicker than the carousel so it starts again too soon. It causes the 'jump' effect because it returns the image in the previous state scale(1).

You should just play around a little with the CSS animations length. For example, if you change all animations from 6000ms to 7000ms, it should do the job.

The zoom effect in the example below is made by CSS @keyframes animation -which I didn't want- and for @keyframes I used background-size with transition, I wanted to make it without @keyframes just simple background-size with transition because it's much better than @keyframes, well, I'll tell you more about it, first see the example if it's okay for you-

Fullscreen Bootstrap 4 carousel Ken Burns and fade

$('#zoomer').carousel({
  interval: 6000,
  pause: false,
  ride: "carousel"
})
.carousel-item {transition-duration: 1s !important}

.item-inner {
  height: 100vh;
  background-repeat: no-repeat;
  background-position: center center;
  overflow: hidden;
  -webkit-animation:kenburns 7000ms linear 0s infinite;
  animation:kenburns 7000ms linear 0s infinite;
}

@keyframes kenburns {
  0%
  {
    background-size: 100% auto;
    transition: all 7s linear;
  }
  100%
  {
    background-size: 110% auto;
    transition: all 7s linear;
  }

}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"></script>

<div id="zoomer" class="carousel slide carousel-fade" data-ride="carousel">

  <!--======= Wrapper for Slides =======-->
  <div class="carousel-inner">

    <!--========= First Slide =========-->
    <div class="carousel-item active">
      <div class="item-inner" style="background-image: url('https://i.picsum.photos/id/874/1920/1680.jpg?hmac=KDczwg-ejraLUmoflMNUBCkt1LyLxNreJptc7RQajFY')"></div>
    </div>

    <!--========= Second Slide =========-->
    <div class="carousel-item">
      <div class="item-inner" style="background-image: url('https://i.picsum.photos/id/878/1920/1680.jpg?hmac=_FQShv6E5HdjI6OKgjozFJQz8SXlT1OwmqijW5jHGQo')"></div>
    </div>

    <!--========= Third Slide =========-->
    <div class="carousel-item">
      <div class="item-inner" style="background-image: url('https://i.picsum.photos/id/870/1920/1680.jpg?hmac=IAkVJX2zYS6BuaMLixYh5xoyOpeDH5WkcGTacBUPPXM')"></div>
    </div>
  </div>
  
  <!--========= Carousel Navigation =========-->
  <a class="carousel-control-prev" href="#zoomer" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
  </a>
  <a class="carousel-control-next" href="#zoomer" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
  </a>
</div>

So, as I was saying, I wanted to make it without @keyframes, and to do that, I need the .active class to be added after a few moments, meaning- the .active class will not be hardcoded, will be added after a few moments so the transition I applied to .carousel-item will work for all the .carousel-item classes when the .active class will be added to them, but now the transition in the first .carousel-item which already has the active class in it, is not working for the obvious reason, the transition is working from the second .carousel-item class.

So if you can add the active class after a few moments, then I hope it would be much better than the @keyframes version. I attached this version too and added an id if you want to try this, see if you can do this & let us know.

A better way without @keyframes, (but working from the second item)

$('#zoomer').carousel({
  interval: 6000,
  pause: false,
  ride: "carousel"
})
.item-inner {
    height: 100vh;
    background-size: 100% auto;
    background-repeat: no-repeat;
    background-position: center center;
    transition: all 6.2s linear;
    overflow: hidden;
}

.carousel-item.active .item-inner {
    transition: all 6.2s linear;
    background-size: 110% auto;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"></script>

<div id="zoomer" class="carousel slide carousel-fade" data-ride="carousel">

  <div class="carousel-inner">

    <div class="carousel-item active" id="activeOnLoad"> <!-- get the ID -->
      <div class="item-inner" style="background-image: url('https://i.picsum.photos/id/874/1920/1680.jpg?hmac=KDczwg-ejraLUmoflMNUBCkt1LyLxNreJptc7RQajFY')"></div>
    </div>

    <div class="carousel-item">
      <div class="item-inner" style="background-image: url('https://i.picsum.photos/id/878/1920/1680.jpg?hmac=_FQShv6E5HdjI6OKgjozFJQz8SXlT1OwmqijW5jHGQo')"></div>
    </div>

    <div class="carousel-item">
      <div class="item-inner" style="background-image: url('https://i.picsum.photos/id/870/1920/1680.jpg?hmac=IAkVJX2zYS6BuaMLixYh5xoyOpeDH5WkcGTacBUPPXM')"></div>
    </div>

  </div>
  <a class="carousel-control-prev" href="#zoomer" role="button" data-slide="prev">
    <span class="carousel-control-prev-icon" aria-hidden="true"></span>
  </a>
  <a class="carousel-control-next" href="#zoomer" role="button" data-slide="next">
    <span class="carousel-control-next-icon" aria-hidden="true"></span>
  </a>
</div>

I updated your Fiddle. If you're ok with it, have the ken burns effect run long, and transition the slide before it hits the end and loops. In this update I ran the KB for 7s instead of 6. Also, needed added transition: all 1s ease-in-out; to the carousel item as the fade was being bypassed by the scale.

http://jsfiddle.net/m1xrsw56/2/

.carousel-inner>.carousel-item
{
  margin:auto;
  height: 100vh;
  width:100%;
  -webkit-transform-origin:50% 50%;
  -moz-transform-origin:50% 50%;
  -ms-transform-origin:50% 50%;
  -o-transform-origin:50% 50%;
  transform-origin:50% 50%;
  -webkit-animation:kenburns 7000ms linear 0s infinite;
  animation:kenburns 7000ms linear 0s infinite;
  transition:all 1s ease-in-out;
  -webkit-transition:all 1s ease-in-out;
  -moz-transition:all 1s ease-in-out;
  -ms-transition:all 1s ease-in-out;
  -o-transition:all 1s ease-in-out;
  transition:all 1s ease-in-out;
}
@-webkit-keyframes kenburns
{
  0%
  {
    -webkit-transform:scale(1);
    -webkit-transition:-webkit-transform 7000ms linear 0s
  }
  100%
  {
    -webkit-transform:scale(1.1);
    -webkit-transition:-webkit-transform 7000ms linear 0s
  }

}
@-moz-keyframes kenburns
{
  0%
  {
    -moz-transform:scale(1);
    -moz-transition:-moz-transform 7000ms linear 0s
  }
  100%
  {
    -moz-transform:scale(1.1);
    -moz-transition:-moz-transform 7000ms linear 0s
  }

}
@-ms-keyframes kenburns
{
  0%
  {
    -ms-transform:scale(1);
    -ms-transition:-ms-transform 7000ms linear 0s
  }
  100%
  {
    -ms-transform:scale(1.1);
    -ms-transition:-ms-transform 7000ms linear 0s
  }

}
@-o-keyframes kenburns
{
  0%
  {
    -o-transform:scale(1);
    -o-transition:-o-transform 7000ms linear 0s
  }
  100%
  {
    -o-transform:scale(1.1);
    -o-transition:-o-transform 7000ms linear 0s
  }

}
@keyframes kenburns
{
  0%
  {
    transform:scale(1);
    transition:transform 7000ms linear 0s
  }
  100%
  {
    transform:scale(1.1);
    transition:transform 7000ms linear 0s
  }

}
<div class="carousel slide carousel-fade animate_text kb_wrapper" data-ride="carousel" data-interval="6000">

    <!--======= Wrapper for Slides =======-->
    <div class="carousel-inner">

        <!--========= First Slide =========-->
        <div class="carousel-item active" style="background-image: url('https://i.picsum.photos/id/878/1920/1680.jpg?hmac=_FQShv6E5HdjI6OKgjozFJQz8SXlT1OwmqijW5jHGQo')">

        </div>

        <!--========= Second Slide =========-->
        <div class="carousel-item" style="background-image: url('https://i.picsum.photos/id/874/1920/1680.jpg?hmac=KDczwg-ejraLUmoflMNUBCkt1LyLxNreJptc7RQajFY')">
        </div>

        <!--========= Third Slide =========-->
        <div class="carousel-item" style="background-image: url('https://i.picsum.photos/id/870/1920/1680.jpg?hmac=IAkVJX2zYS6BuaMLixYh5xoyOpeDH5WkcGTacBUPPXM')">

        </div>

Related