Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

fearless3955

macrumors newbie
Original poster
Sep 12, 2008
8
0
I've struggled to implement some cool script for a self-scrolling image gallery but the start point of the scroll is outside the cell so it takes time to fill the area completely, and then, at the end of all the images, it takes a while for the sequence to recommence because of the same gap.
1. Most important - can anyone see how to amend the code so it will start with the cell full (instead of coming on from the side ) and then will loop forever WITHOUT a recurring gap?
2. Although the script seems to work (in Safari) Dreamweaver doesn't like where I've positioned Step 3:
<body onload="startw();">
so does it need to be bundled with other existing code somewhere, or where is it supposed to go?
Here's my experimental page:
http://www.suemo.com/aboutus_test2.html
I'm sure there's a simple answer?!
 
OK, I worked out a different Image Carousel that should work for what you're doing. I haven't thoroughly tested in many browsers, but we'll see.

Place this JavaScript block inside the head tag:
PHP:
<script type="text/javascript">
//<![CDATA[
ImageCarousel = function()
{
  var images = [
    'image01.jpg',
    'image02.jpg',
    'image03.jpg'
  ];
  var offsets = new Array(images.length);
  var v = {
    //**** User Preferences ****
    id: 'carousel',  // tag where carousel should be placed
    step: 4,         // speed, 1-25
    //**** End user preferences ****
    timer: null,
    widthAll: 0,
    count: 0
  };
  Init = function() {
    // total width
    v['wAll'] = 0;
    // preload images and gather widths
    for (var x=0, i=new Array(); x < images.length; x++) {
      i[x] = new Image(); i[x].src = images[x];
      offsets[x] = 0;
      i[x].onload = function(){ Totaler(this); };
    }
    // Place images onto page
    var txt = '';
    for (var x=0, y=images.length; x<y; x++) {
      txt += "<img src='"+ images[x] +"' style='position:absolute; top:0;' "+
        "alt='' />";
    }
    document.getElementById('carousel').innerHTML = txt;
    v['imgs'] = document.getElementById('carousel').getElementsByTagName('img');
  };
  Totaler = function(i) {
    v['wAll'] += i.width;
    if (++v['count'] >= images.length) {
      var max = 0;
      for (var x=0, y=v['imgs'].length; x<y; x++) {
        max = (v['imgs'][x].height > max) ? v['imgs'][x].height : max;
      }
      document.getElementById('carousel').style.height = max +'px';
      Start();
    }
  };
  Start = function() {
    // set initial spots
    var t = 0;
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      if (x > 0) {
        offsets[x] = t;
        v['imgs'][x].style.left = (t +'px');
        t += v['imgs'][x].width;
      }
      else {
        v['imgs'][x].style.left = (t +'px');
        t += v['imgs'][x].width;
      }
    }
    Left();
  };
  Left = function() {
    for (var x=0, y=images.length; x<y; x++) {
      if ((offsets[x] - v['step']) < (0 - v['imgs'][x].width)) {
        offsets[x] = v['wAll'] - v['imgs'][x].width - v['step'];
      }
      else { offsets[x] -= v['step']; }
    }
    Redraw();
    v['timer'] = setTimeout(function(){Left()}, 70);
  };
  Redraw = function() {
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      v['imgs'][x].style.left = offsets[x] +'px';
    }
  };
  window.onload = Init;
}();
//]]>
</script>
Change the image locations for the images variable near the top, same as you did for your current script. You can also adjust scroll speed by adjusting the step variable also near the top (between 1 and 25).

Place this with your CSS (you'll need to adjust the width for your layout and probably can get rid of the margin):
Code:
#carousel {
 position: relative;
 margin: 0 auto;
 width: 800px;
 overflow: hidden;
}
Lastly, place this HTML where you want the carousel:
HTML:
<div id="carousel"></div>
If you have trouble getting this in place let me know.
 
I have to say, you are without a doubt the most helpful person I've ever had the pleasure to read the posts of!

Thanks, I appreciate that. I help where I can and pass on the knowledge the internet has taught me, and to lead by example. Mac Rumors is one of the friendliest forums I've seen on the internet. There's rarely any name calling or bullying, just Mac people helping Mac people (and the occasional Windows person who needs our help) and I try to encourage that continuation by providing helpful guidance (and the occasional not-so-helpful comments).

On a note about my code above. If anyone gives it a try, post your thoughts on it (code-wise or presentation-wise). I'm likely to turn it into a more formal script that people can implement on their own site more easily than what I have posted here, which will of course be available for free on my site whenever I get to that.
 
Thanks

Many thanks for that. I will work with it shortly (though in the meantime I had to go the Flash route, which makes for a 100k file and would be a pain to edit) but I can't tell you how grateful I am that you've now set me on the right track.
 
Reverse Direction?

Angelwatt,
Thanks for the script. We're a mix of Windows folk and Mac folk and I actually dropped your script into a site running on .net and tied with with an array built in C# code. Everything is working great!

I put it on its own page and then referenced that in an iframe so I could display the scrolling images continually in the banner area. Returns a very nice effect.

I was wondering if there was a way to redirect the script to scroll to the right. Understandably reading left to right lends it self to adding images with position absolute, but I thought I'd ask. Rolling in the other direction really lends itself better to the overall design of the site.

Thanks!
tnriverfish
 
I was wondering if there was a way to redirect the script to scroll to the right.

This crossed my mind when I wrote it, but wasn't needed at the time so let it go. I thought it was a simple matter of reversing some signs, but it took a touch more than that. Mainly doing a little spatial reorientation in my head to make sense of what needed to be done. Below is the missing Right function that you need. Just add the below code (like after the Left function) and at the end of the Init function, change the line to call Right instead of Left.

Glad to hear the script worked for you too. I haven't thrown it in any real world web sites to see how it behaves. I'm still surprised this code wasn't out there somewhere, or at least I never ran across any code like this, but it guess there were some who were looking for it.

PHP:
  Right = function() {
    for (var x=0, y=images.length; x<y; x++) {
      if ((offsets[x] + v['step']) > (v['wAll'] - v['imgs'][x].width)) {
        offsets[x] = 0 - v['imgs'][x].width + v['step'];
      }
      else { offsets[x] += v['step']; }
    }
    Redraw();
    v['timer'] = setTimeout(function(){Right()}, 70);
  };
 
Thanks! The first version is running well on my machine.
I'll let you know when I put a beta up on the web.

Perhaps I'll see if they are up for one left and one right ;-)
 
Thanks to tnriverfish's trying out of the script it became apparent that the script does not work in IE. I'm sure we're all shocked. Thankfully I've run into this specific problem IE has with acknowledging a img.onload event for images already existing in the cache. Below is the script updated to work on IE5+ (oh yes, it works that far back) as well as all of the other browsers I tested (Firefox, Safari, Opera, Chrome) though only checked the more recent versions of those browsers. The CSS and HTML provided earlier has not changed.

PHP:
<script type="text/javascript">
//<![CDATA[
ImageCarousel = function()
{
  var images = [
    'image01.jpg',
    'image02.jpg',
    'image03.jpg'
  ];
  var offsets = new Array(images.length);
  var v = {
    //**** User Preferences ****
    id: 'carousel',  // tag where carousel should be placed
    step: 4,         // speed, 1-25
    //**** End user preferences ****
    timer: null,
    widthAll: 0,
    count: 0
  };
  Init = function() {
    // total width
    v['wAll'] = 0;
    // Place images onto page
    var txt = '';
    for (var x=0, y=images.length; x<y; x++) {
      txt += "<img src='"+ images[x] +"' style='position:absolute; top:0;' "+
        "alt='' />";
    }
    document.getElementById('carousel').innerHTML = txt;
    v['imgs'] = document.getElementById('carousel').getElementsByTagName('img');
    // preload images and gather widths
    for (var x=0; x < images.length; x++) {
      var img = new Image();
      offsets[x] = 0;
      img.onload = function(){ Totaler(this); };
      img.src = images[x];
    }
  };
  Totaler = function(i) {
    v['wAll'] += i.width;
    if (++v['count'] >= images.length) {
      var max = 0;
      for (var x=0, y=v['imgs'].length; x<y; x++) {
        max = (v['imgs'][x].height > max) ? v['imgs'][x].height : max;
      }
      document.getElementById('carousel').style.height = max +'px';
      Start();
    }
  };
  Start = function() {
    // set initial spots
    var t = 0;
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      if (x > 0) {
        offsets[x] = t;
        v['imgs'][x].style.left = (t +'px');
        t += v['imgs'][x].width;
      }
      else {
        v['imgs'][x].style.left = (t +'px');
        t += v['imgs'][x].width;
      }
    }
    Right();
  };
  Left = function() {
    for (var x=0, y=images.length; x<y; x++) {
      if ((offsets[x] - v['step']) < (0 - v['imgs'][x].width)) {
        offsets[x] = v['wAll'] - v['imgs'][x].width - v['step'];
      }
      else { offsets[x] -= v['step']; }
    }
    Redraw();
    v['timer'] = setTimeout(function(){Left()}, 70);
  };
  Right = function() {
    for (var x=0, y=images.length; x<y; x++) {
      if ((offsets[x] + v['step']) > (v['wAll'] - v['imgs'][x].width)) {
        offsets[x] = 0 - v['imgs'][x].width + v['step'];
      }
      else { offsets[x] += v['step']; }
    }
    Redraw();
    v['timer'] = setTimeout(function(){Right()}, 70);
  };
  Redraw = function() {
    for (var x=0, y=v['imgs'].length; x<y; x++) {
      v['imgs'][x].style.left = offsets[x] +'px';
    }
  };
  window.onload = Init;
  return { Left:Left, Right:Right };
}();
//]]>
If you look at the code closely you'll see that nothing really changed except the order of the code in the Init function. IE just sucks like that.

Late Edit: I've given this script some updates and gave it a home on my site.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.