Avatar of Brad Bansner
Brad Bansner
 asked on

Using jQuery to scroll and reposition images inside a overflow:hidden DIV

On this test page:
http://www.partnersdesign.net/lieverhymanpotter 

I've got a series of 2000px wide images with position:absolute, spaced out at 2000px intervals so they are all lined up left-to-right (but only the left-most image is visible).

In the attached script, every three seconds I animate anything with class=slide 2000px to the left, which slides the whole series to the left.

Then what I am trying to do is reposition the left-most image that just slid off the screen, 12000px to the right, so it put back at the end of the line again.

I think I have close to having this work, but there are some obvious problems. And the positioning is different when you view this in different browsers, which I don't quite understand.

I'm wondering if something about the way I'm doing my callback is incorrect.

Anyway, would appreciate another set of eyes on this. Thank you!

var curImg=1;
var maxImg=6;
var intervalID=setInterval(homeAnimation,3000);

function homeAnimation(){
	console.log('curImg='+curImg);
	console.log('position='+$('#slide'+curImg).position().left);

	$('.slide').animate({left:'-=2000px'}, function(){
		$('#slide'+curImg).animate({right:'+=12000px'});
	});

	if (curImg===maxImg){curImg=1;} else {curImg++;}
};

Open in new window

JavaScript

Avatar of undefined
Last Comment
Christopher Kile

8/22/2022 - Mon
Michel Plungjan

var curImg=1;
var maxImg=6;
var intervalID=setInterval(homeAnimation,3000);

function homeAnimation(){
      console.log('curImg='+curImg);
      console.log('position='+$('#slide'+curImg).position().left);

      $('.slide').animate({left:'-=2000px'});

      if (curImg===maxImg) {
          curImg=1;
          $('#slide'+curImg).animate({right:'+=12000px'});
        }
        else {curImg++;}
};
Brad Bansner

ASKER
That doesn't seem to have really done anything. Safari is still not animating the right distance, nor is Chrome.
Michel Plungjan

Here ya go.

You can set the position when they slide back instead of sliding them
And move the counter if you want to reset immediately after slide 5

var curImg=1,maxImg,pos=[];

$(function(){
  var intervalID=setInterval(homeAnimation,3000);
  maxImg=$('.slide').length;
  $('.slide').each(function(i) { pos[i] = $(this).position().left});
});

function homeAnimation(){
  $('.slide').animate({left:'-=2000px'});
  if (curImg===maxImg){
    curImg=1;
    $('.slide').each(function(i) {
      $(this).animate({left:pos[i]});
    });
  } else {
    curImg++;
  }
};

Open in new window

All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
Brad Bansner

ASKER
That results in a visible re-shuffle (at the end of the series) that I wanted to avoid.

I tried modifying my original script to adjust the z-index values on the fly (it makes sure that the next image to be animated has a higher z-index than the current one, so when the current one flips back to the end of the line, it slides under instead of over), and that seems to have fixed the slides so it is now a seamless, endless loop. Great!

However, the positioning of the animated slides only seems to work properly in Firefox. In Chrome and Safari, they are offset too far to the left by 226px (this amount varies depending on how wide you have your browser window).

The original positioning of the first slide (before the script is run) is set like this:

#slide1{width:978px;height:481px;top:0px;left:50%;margin-left:-1000px;padding:262px 0px 0px 1022px;}

The DIV is 2000px wide, so I set left to 50% then reduce the left margin by -1000px, which centers it on the screen no matter how wide your browser window is. That works fine in all browsers.

Then, the animation simply moves everything to the left 2000px. The 2nd slide has CSS positioning like this:

#slide2{width:2000px;height:743px;top:0px;left:50%;margin-left:1000px;padding:0px;}

Again, 50% left, plus 1000px this time (positive) on the left margin (because I want it positioned 2000px to the right of the first slide, so they butt up against each other).

Yet, when I do this:

$('.slide').animate({left:'-=2000px'});

...instead of slide #2 being centered on the screen, it is offset to the left. Slide #3 is offset to the left by the same amount... the amount of offset does not change no matter how many times I let the entire series animate.

I don't understand why these values aren't lining up. I'm not sure if this is a CSS problem, or a problem with my script, or just a general browser inconsistency thing and I need to try something else? Or perhaps something is going wrong in the interactions between the jQuery animation and the way I am positioning things in CSS?

I feel like I must be really close to getting this right.

var curImg=1;
var nextImg;
var maxImg=6;
var newZindex;
var intervalID=setInterval(homeAnimation,3000);

function homeAnimation(){
	if (curImg===maxImg){
		nextImg=1;
	} else {
		nextImg=curImg+1;
	}

	newZindex=parseInt($('#slide'+nextImg).css('z-index'))+1;

	console.log('curImg='+curImg);
	console.log('nextImg='+nextImg);
	console.log('position='+$('#slide'+curImg).css('left'));
	console.log('newZindex='+newZindex);
	console.log(' ');

	$('.slide').animate({left:'-=2000px'});
	$('#slide'+nextImg).css('z-index', newZindex);
	$('#slide'+curImg).animate({left:'+=12000px'});

	if (curImg===maxImg){
		curImg=1;
	} else {
		curImg++;
	}
};

Open in new window

Michel Plungjan

Just take my code, change the slide when counter is max to no slide and you will be fine
Brad Bansner

ASKER
I'm not sure exactly what you mean by that last statement.

And also, the Safari/Chrome positioning still doesn't work.
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Michel Plungjan

$('.slide').each(function(i) {
      $(this).css({left:pos[i]});
    });

Open in new window

Michel Plungjan

Or css("left",pos[ i])
Brad Bansner

ASKER
I can't get it to work, and positioning still wrong in Safari/Chrome. Here is what I have:

var curImg=1,maxImg,pos=[];

$(function(){
	var intervalID=setInterval(homeAnimation,3000);
	maxImg=$('.slide').length;
	$('.slide').each(function(i){
		pos[i]=$(this).position().left
	});
});

function homeAnimation(){
	$('.slide').animate({left:'-=2000px'});
	if (curImg===maxImg){
		curImg=1;
		$('.slide').each(function(i){
			$(this).css({left:pos[i]});
		});
	} else {
		curImg++;
	}
};

Open in new window

I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
ASKER CERTIFIED SOLUTION
Michel Plungjan

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
Brad Bansner

ASKER
I copied and pasted that code, the scrolling is working:

http://www.partnersdesign.net/lieverhymanpotter

After the last slide, it goes blank, then the 1st slide reappears.

Are you able to view this in either Safari or Chrome? The slides are still not positioned right, after the 1st slide is replaced.
Michel Plungjan

Yeah I see it and have no idea why
Brad Bansner

ASKER
OK, good enough, you did solve my scrolling problem. Thanks!
Get an unlimited membership to EE for less than $4 a week.
Unlimited question asking, solutions, articles and more.
Christopher Kile

http://cssherald.com/153/google-chrome-and-apple-safari-css-only-hack/
http://stackoverflow.com/questions/3795888/extra-padding-on-chrome-safari-webkit-any-ideas

Here's a couple of links that might help you attack the Safari/Chrome issue (not surprising they have the same issue, they are using the same underlying WebKit API).