skip to Main Content

I have a background image set to loop infinitely on a 10 second CSS animation. I’m using jQuery to find the height of the image based on the users screen size. Then I use background-position-y and go from 0 to exactly the height of the image. This creates a smooth loop, for any desktop screen size (A separate bg image will be used for mobile).

Issue: On page load, the animation appears to not work correctly on the first iteration of the loop. The image pans slowly for 10s, "jumps" back to the original position, then works correctly for all future iterations of the loop.

Looking for help on how to make the first animation loop, the first 10s to work how it should/like the remaining loops and the path appears to be infinite.

JS Fiddle: https://jsfiddle.net/bennimbl/7xkyhgz2/3/

View the fiddle, note it’s slowness for 10 seconds, then note it works correctly after then.

2

Answers


  1. The problem is the starting set up of the background image.

    There is a bit of a mixture in this code. It seems as though an attempt was made to use CSS keyframes for the animation and that this was then abandoned and JS/jquery used instead on a timeout.

    This snippet simplifies things by getting rid of JS/jquery animation and going back to the keyframes (this can in any case help CPU usage).

    The code already sets a CSS variable –height to the height of the current viewport so this is used in the keyframes to move the background image from a top position of 0 to a top position of -this height.

    There was a spurious : after animation in the CSS set up which has been removed.

    The only other change that has been made is to set the background image to top 0 from the start rather than at the bottom of the viewport.

    var fullhdWidth = 1920;
    var fullhdHeight = 2685;
    var fullhdRatio = fullhdWidth / fullhdHeight;
    
    $('#s1Bg').ready(function() {
      var containerWidth = $(this).width();
      var containerHeight = $(this).height();
      var containerRatio = containerWidth / containerHeight;
      var realWidth = null;
      var realHeight = null;
    
      if (containerRatio > fullhdRatio) {
        realWidth = containerWidth;
        realHeight = containerWidth / fullhdRatio;
        //alert(realWidth + ' ' + realHeight);
      } else {
        realWidth = containerHeight * fullhdRatio;
        realHeight = containerHeight;
        //alert(realWidth + ' ' + realHeight);
      }
    
      $('<style>').text(`:root{--height: ${realHeight};}`).appendTo(document.head);
    
    
      $("#s1Bg").css({
        'width': '100vw',
        'height': '100vh',
        'margin': '0',
        'background': '#000000 url("https://iili.io/sVrZXe.jpg") 0% 0%/cover repeat-y',
        'animation': 'rideup 10s linear infinite'
      });
    
    });
    body {
      margin: 0;
    }
    
    @keyframes rideup {
      from {
        background-position-y: 0;
      }
      to {
        background-position-y: calc(-1px * var(--height));
      }
    }
    <head>
      <title></title>
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
    
    
      <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
    </head>
    <div id="s1Bg" class="s1-bg"></div>
    Login or Signup to reply.
  2. I’ve made a little change on your css and gotime function to start at the realHeight and then animate to background-position-y: 0. I moved some css to the css file to since it didn’t belong in the js file. Though i couldn’t really figure out why it didn’t worked out in the previous fiddle it does in this one

    JS:

     $("#s1Bg").css({
                'background-position-y': realHeight,
                    'animation:' : 'rideup 10s linear infinite'
                });
    
                var gotime = function() {
                    $('#s1Bg').animate({
                        'background-position-y': 0,
                    }, 10000, 'linear', function() {
                        $(this).css('background-position-y', realHeight);
                        gotime();
                    });
                }
    

    CSS:

    #s1Bg {
      height: 100vh;
      width: 100vw;
      margin: 0;
      background-image: url('https://iili.io/sVrZXe.jpg');
      background-size: cover;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search