0

I'm currently working on an image rotator. The rotation part is complete, however I'm expanding the functionality based on a need that I've found.

Goal: Rotate through a preset list of slides that contain hardcoded images, however on each subsequent rotation, use js to swap to a new image for specific slides that require a variation.

The script below works fine, but I feel like it's not the most efficient way to go about this. Currently I'm tackling it by running a new loop and function for each of the specific slides that I've chosen to be the "different" ones. My guess is there is a way to do it using one function and loop, but I'm not quite sure how to go about it.

Anology: Let's say I have an image rotator that displays a list of cars and every 5 seconds it rotates to the next slide. Each slide is designated for a different model of car, however for some models, I want to display a different variation of that model on each iteration of the entire rotator.

Example:

Here is a list of how each pass of the rotator would print.

- Ford Focus
- Toyota Celica
- Hyundai Elantra
- Dodge Ram
- Motorcycle

- Ford Focus
- Toyota Celica GTS
- Hyundai Elantra
- Dodge Ram w/ additional accessories
- Motorcycle

- Ford Focus
- Toyota Celica w/ Spoiler
- Hyundai Elantra
- Dodge Ram different color
- Motorcycle

Here is my current script:

<script>
window.onload=function() {
    imgCont = document.getElementById('example1');
    c_imgCont = document.getElementById('example2');
}

var myIndex = 0;
carousel();

function carousel() {
    var i;
    var x = document.getElementsByClassName("slide");

    for (i = 0; i < x.length; i++) {
       x[i].style.display = "none";  
    }
    myIndex++;
    if (myIndex > x.length) {myIndex = 1; 
     if (typeof(imgCont) != 'undefined' && imgCont != null)
  {
   swapImage(); 
  }

  if (typeof(c_imgCont) != 'undefined' && c_imgCont != null)
  {
   swapImageExample2();
  }

    }
    x[myIndex-1].style.display = "block";  
    setTimeout(carousel, x[myIndex-1].dataset.timing);
}


    
var picPaths = ['image1.png','img2.png','img3.png','img4.png'];
var curPic = -1;
//preload the images for smooth animation
var imgO = new Array();
for(i=0; i < picPaths.length; i++) {
    imgO[i] = new Image();
    imgO[i].src = picPaths[i];
}

function swapImage() {
    curPic = (++curPic > picPaths.length-1)? 0 : curPic;
    imgCont.src = imgO[curPic].src;
}

var c_picPaths = ['otherimg1.png','otherimg2.png'];
var c_curPic = -1;
//preload the images for smooth animation
var c_imgO = new Array();
for(l=0; l < c_picPaths.length; l++) {
    c_imgO[l] = new Image();
    c_imgO[l].src = c_picPaths[l];
}

function swapImageExample2() {
    c_curPic = (++c_curPic > c_picPaths.length-1)? 0 : c_curPic;
    c_imgCont.src = c_imgO[c_curPic].src;
}


</script>
user1592307
  • 11
  • 1
  • 3
  • Careful with terminology - [image rotation](http://stackoverflow.com/questions/16794310/rotate-image-with-javascript) vs [image swapping](http://stackoverflow.com/questions/9424759/swap-multiple-images-from-javascript-array) – James May 08 '17 at 18:14
  • Apologies, in my industry this specific product is referred to as a rotator (as it rotates through slides automatically). Definitely need to be careful with that! – user1592307 May 09 '17 at 02:05

1 Answers1

0

Why not just adjust your data structure so that any "image" in the picPaths array can be an array of image paths. Then use a function to get the image path to show. See simple example below.

Notice the structure of picPaths. Also notice that the 2nd and 4th images in the rotation (transport, nature) rotate through different images each iteration of the picPaths array.

<img id="example1" src="http://lorempixel.com/400/200/cats/1/"/>


<script>
    window.onload = function() {
        imgCont = document.getElementById('example1');
        swapImage();
    }

    var picPaths = [
            "http://lorempixel.com/400/200/cats/1/",
            [
                "http://lorempixel.com/400/200/transport/1/",
                "http://lorempixel.com/400/200/transport/2/",
                "http://lorempixel.com/400/200/transport/3/",
                "http://lorempixel.com/400/200/transport/4/"
            ],
            "http://lorempixel.com/400/200/animals/1/",
            [
                "http://lorempixel.com/400/200/nature/1/",
                "http://lorempixel.com/400/200/nature/2/",
                "http://lorempixel.com/400/200/nature/3/",
                "http://lorempixel.com/400/200/nature/4/",
                "http://lorempixel.com/400/200/nature/5/"
            ],
            "http://lorempixel.com/400/200/sports/1/"
        ],
        curImg = 0;

    function getImagePath(path) {
        if(Array.isArray(path)) {
            var temp = path.shift();
            path.push(temp);
            return temp;
        }
        else {
            return path;
        }
    }

    function swapImage() {
        curImg = curImg < (picPaths.length - 1) ? curImg : 0;        
        var imgPath = getImagePath(picPaths[curImg]);
        console.clear();
        console.log('current index in picPaths:', curImg, 'current image path to display:', imgPath);
        imgCont.src = imgPath;
        curImg++;
        setTimeout(function() {
            swapImage();
        }, 4000);
    }
</script>

Based on your comment I made a 2nd example. I think this is what you mean.

window.onload = function() {
    carousel(picPaths, 'slide');
};

var picPaths = [
        "https://placeimg.com/640/480/any/sepia/1",
        [
            "https://placeimg.com/640/480/tech/1",
            "https://placeimg.com/640/480/tech/2",
            "https://placeimg.com/640/480/tech/3",
            "https://placeimg.com/640/480/tech/4"
        ],
        "https://placeimg.com/640/480/animals/1",
        [
            "https://placeimg.com/640/480/nature/1",
            "https://placeimg.com/640/480/nature/2",
            "https://placeimg.com/640/480/nature/3",
            "https://placeimg.com/640/480/nature/4",
            "https://placeimg.com/640/480/nature/5"
        ],
        "https://placeimg.com/640/480/arch/1"
    ];

function carousel(imgPaths, imgClass) {
    var imgs = document.getElementsByClassName(imgClass);

    Array.prototype.forEach.call(imgs, function(imgElem, idx) {
        var timing = imgElem.dataset.timing,
            path = imgPaths[idx];

        swapImage(imgElem, path, timing);
    });

    function getImagePath(path) {
        if(Array.isArray(path)) {
            var temp = path.shift();
            path.push(temp);
            return temp;
        }
        else {
            return path;
        }
    };

    function swapImage(imgElem, path, timing) {
        var imgPath = getImagePath(path);

        imgElem.src = imgPath;
        setTimeout(function() {
            swapImage(imgElem, path, timing);
        }, timing);
    };
}
.slide {
  width: 100px;
}
<div id="container">
  <img id="slide_1" class="slide" src="" data-timing="8000">
  <img id="slide_2" class="slide" src="" data-timing="4000">
  <img id="slide_3" class="slide" src="" data-timing="10000">
  <img id="slide_3" class="slide" src="" data-timing="6000">
</div>
gforce301
  • 2,944
  • 1
  • 19
  • 24
  • Thanks, I see exactly what you're saying here! The only issue that I see is that it uses a set timeout duration. How can I make that dynamic for each slide? Just to provide an example of what I do now: ` ` Data-timing is the timeout value for each slide. – user1592307 May 09 '17 at 02:17
  • Added a 2nd example of what I think you wanted. – gforce301 May 09 '17 at 15:29