Infinite scrolling div glitching with images

179 Views Asked by At

I'm currently using the following javascript as shown below. It's working well when I place just text within the div .image_scroll_3 but as soon as I insert images the scroll glitches and won't move past the top of the image.

Any advice would be much appreciated

JS

  <script>
  (function($, undefined) {
  $.fn.loopScroll = function(p_options) {
  var options = $.extend({
    direction: "upwards",
    speed: 60
  }, p_options);

  return this.each(function() {
  var obj = $(this).find(".image_scroll_2");
  var text_height = obj.find(".image_scroll_3").height();
  var start_y, end_y;
  if (options.direction == "downwards") {
    start_y = -text_height;
    end_y = 0;
  } else if (options.direction == "upwards") {
    start_y = 0;
    end_y = -text_height;
  }

  var animate = function() {
    // setup animation of specified block "obj"
    // calculate distance of animation    
    var distance = Math.abs(end_y - parseInt(obj.css("top")));

      //alert("animate " + obj.css("top") + "-> " + end_y + " " + distance);

    //duration will be distance / speed
    obj.animate(
      { top: end_y },  //scroll upwards
      1500 * distance / options.speed,
      "linear",
      function() {
          // scroll to start position
          obj.css("top", start_y);
          animate();    
      }
    );
  };

  obj.find(".image_scroll_3").clone().appendTo(obj);
  $(this).on("mouseout", function() {
    obj.stop();
  }).on("mouseout", function() {
    animate(); // resume animation
  });
  obj.css("top", start_y);
  animate(); // start animation

  });
  };
  }(jQuery));

  $("#example4").loopScroll({ speed: 700 });
  </script> 
1

There are 1 best solutions below

0
On BEST ANSWER

I think the problem is that your text_height is calculated before the images are actually loaded inside your .image_scroll_3 elements. So you'll need to wait for the images to load.

Put your loopScroll call inside a $(window).load like so:

$(window).load(function(){
    $('#example4').loopScroll({speed:700});
});

That massive glitch should now be gone as the fix above should have helped mitigate it.

However, there is still some unwanted jank / stutter (don't want to use the word glitch again, lets keep it reserved for the initial problem) in movement of all images if you notice and I am guessing that is probably because we are animating the whole thing too fast. Passing in speed like 100 or 200 resolves that but this is not really a solution because, ideally, you should be able to put in any speed value and it should just produce smooth animations out of it.

I am working on exactly the same thing but before that, I want to know if the above fix for the glitch helps you and we are finally done with it? Let me know.

Update:

Here is my version that I spoke of earlier, for your perusal.

Because all you are trying to do is loop images in a very linear fashion, I, for one, do not see the need to rely on animate() function of jQuery. There is requestAnimationFrame API that I have leveraged instead. In fact, in my demonstration below I have completely abandoned jQuery in favour of vanilla JavaScript only because I kept finding alternatives to pretty much everything we needed to do in this demo. But of course, this is also a very subjective matter; a taste thing; so if you want to go with jQuery, then by all means.

Another fundamental change I brought is rather than updating top values, I have resorted to updating translateY values.

Take a look at this jsFiddle and let me know if it fits your needs.

JavaScript code of which is as belows:

// [http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/]
window.requestAnimFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(callback){window.setTimeout(callback,1000/60);};})();
var main=null;
var imageScroll2=null;
var imageScroll3=null;
var totalHeight=null;
var initY=null;
var destY=null;
var currY=null;
var increment=null;
var direction=null;
var UP=null;
var DOWN=null;
var isPlaying=null;
function init(){
    main=document.getElementById('example4');
    imageScroll2=main.getElementsByClassName('image_scroll_2')[0];
    imageScroll3=main.getElementsByClassName('image_scroll_3')[0];
    totalHeight=imageScroll3.clientHeight;
    UP='upwards';
    DOWN='downwards';
    isPlaying=true;
    direction=UP;
    increment=10;
    if(direction===DOWN){
        initY= -totalHeight;
        destY=0;
    }else{
        initY=0;
        destY= -totalHeight;
    }
    currY=initY;
    imageScroll2.appendChild(imageScroll3.cloneNode(true));
    if(imageScroll2.addEventListener){
        imageScroll2.addEventListener('mouseover',function(){isPlaying=false;},false);
        imageScroll2.addEventListener('mouseout',function(){isPlaying=true;},false);
    }else{
        imageScroll2.attachEvent('onmouseover',function(){isPlaying=false;});
        imageScroll2.attachEvent('onmouseout',function(){isPlaying=true;});
    }
    requestAnimFrame(render);
}
function render(){
    if(isPlaying){
        imageScroll2.style.transform='translate(0px,'+currY+'px)';
        if(direction===DOWN){
            currY+=increment;
            if(currY>=destY){currY=initY;}
        }else{
            currY-=increment;
            if(currY<=destY){currY=initY;}
        }
    }
    requestAnimFrame(render);
}
//
init();