dustymethod/BrowserImageSlideshow

Option to sort images according to the numerical order

Closed this issue · 2 comments

Hi there! Ever since found this plugin it helped me a lot to do my work especially because of the OBS Slideshow limitations. I find it very useful if you could add an option to sort the images according to the alphanumeric order. I hope it helps others a lot as well.

Hi there @NetworkJBM ,

Below is a modified version of BrowserImageSlideshow.html that should sort images alpha numerically. Please feel free to try it out, and let me know if the sort is correct.

The only difference is the added alphanumericSort function, and a call to that function.

<!DOCTYPE html>
<!--

BrowserImageSlideshow
https://github.com/dustymethod/BrowserImageSlideshow
https://obsproject.com/forum/threads/browser-image-slideshow.110157/

-->
<div id="imageContainer"></div>
<style>
    *{
        border-color: transparent;
        background-color: transparent;
    }
    img {
        position: fixed;
        object-fit:contain;
        width: 100%;
        height: 100%;
        border-color: transparent;
    }
    body {
        background-color: transparent;
        margin: auto;
        overflow: hidden;
    }
</style>

<script src="jquery-3.4.1.min.js"></script>
<script src="images/images.js"></script>
<script src="settings.js"></script>
<script>

// modes (defined in settings.js):
// 0: Random order (default)
// 1: Alphabetical order
// 2: Alphabetical order (start on random image)

// setup image src strings
let images = imageNamesStr.split("\n");
images.shift();
images.pop();
for (let i = images.length-1; i >= 0; i--) {
    // remove js, sh, or directory
    let remove = images[i].includes(".js") || images[i].includes(".sh") || !images[i].includes(".") || images[i].includes(".git");
    if (remove) {
        images.splice(i, 1);
    }
}

// Sort list of images alpha numerically
function alphanumericSort() {
    // sorting options https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator
    const collator = new Intl.Collator(undefined, {
        numeric: true
    });
    images.sort((a, b) => {
        return collator.compare(a, b);
    });

    console.log(images);
}

alphanumericSort();

// setup indexes for shuffling
let indexes = new Array();
for(let i = 0; i < images.length; i++) {
    images[i] = "images/" + images[i];
    indexes.push(i);
}

// setup img elements
let topImage = document.createElement("img");
let botImage = document.createElement("img");
let imageContainer = document.getElementById("imageContainer");
imageContainer.appendChild(botImage);
imageContainer.appendChild(topImage);
topImage.id = "topImage";
botImage.id = "botImage";

let fadeDuration = slideDuration * 0.25;
let slideshowFunc;
let index = 0;
let fadeInTop = true; // bool for deciding if top image fades in or out
let isSlideshowPaused = false;
let isSlideshowVisible = true;
let isTransitionInProgress = false; // skip animation if already in progress

function shuffle(a) {
    for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
}

function randomizeIndex(max) {
    index = Math.floor(Math.random() * max); // [0, max)
}

// called each interval of setInterval()
function update() {
    if (index === images.length-1 && loopSlideshow === false) {
        clearInterval(slideshowFunc);
        isSlideshowPaused = true;
        return;
    }
    getNextSlide();
}

function getNextSlide() {
    index = index === images.length - 1 ? 0 : index + 1;
    if (index === 0 && mode === 0) {
        shuffle(indexes);
    }
    
    let imageSrc = images[indexes[index]];
    fadeInImage(imageSrc);
}

function getPreviousSlide() {
    index = index === 0 ? images.length - 1 : index - 1;
    let imageSrc = images[indexes[index]];
    fadeInImage(imageSrc);
}

function fadeInImage(imageSrc) {
    if (fadeInTop) { topImage.src = imageSrc; }
    else { botImage.src = imageSrc; }
    
    if (isTransitionInProgress) {
        $("#topImage").stop(true, true);
        $("#botImage").stop(true, true);
    }
    
    isTransitionInProgress = true;
    $("#botImage").animate(
        { opacity: fadeInTop ? 0.0 : 1.0 },
        { duration: fadeDuration }
    );

    $("#topImage").animate(
        { opacity: fadeInTop ? 1.0 : 0.0 },
        {
            duration: fadeDuration,
            done: function() {
                isTransitionInProgress = false;
            }
        }
    );

    fadeInTop = !fadeInTop;
}

function pause() {
    if (isSlideshowPaused) return;
    clearInterval(slideshowFunc);
    isSlideshowPaused = true;
}

function resume() {
    if (!isSlideshowPaused) return;
    getNextSlide(); // get next slide without waiting for setInterval delay
    slideshowFunc = setInterval(update, slideDuration);
    isSlideshowPaused = false;
}

function restart() {
    $("#topImage").stop(true, true);
    $("#botImage").stop(true, true);
    clearInterval(slideshowFunc);
    start();
}

// called once when the browser source loads or restarts
function start() {
    topImage.style.opacity = "0.0";
    botImage.style.opacity = "0.0";
    
    if (images.length > 0) { // if at least 1 image, show the first image
        
        if (mode === 0) { // random mode
            shuffle(indexes);
        } else if (mode === 2) { // choose random image to start on
            randomizeIndex(images.length);
        }
    
        botImage.src = images[indexes[index]];
        $("#botImage").animate(
            { opacity: 1.0 },
            { duration: fadeDuration }
        );
    }

    if (startWithAutoplay && images.length > 1) {
        slideshowFunc = setInterval(update, slideDuration);
    } else {
        isSlideshowPaused = true;
    }
}

start();

// handle hotkey events from OBS
document.addEventListener("keydown", (event) => {
    let key = "";
    try { key = event.key; } 
    catch (error) {
        console.log(error);
        return;
    }

    switch (key) {
        case "1": pause(); break;
        case "2": resume(); break;
        case "3": getNextSlide(); break;
        case "4": getPreviousSlide(); break;
        case "5": // toggle visibilty
            if (isSlideshowVisible) {
                imageContainer.style.opacity = 0.0;
                isSlideshowVisible = false;
            }  else {
                imageContainer.style.opacity = 1.0;
                isSlideshowVisible = true;
            }
            break;
        case "6": // toggle pause
            if (isSlideshowPaused) {
                resume();
            } else {
                pause();
            }
            break;
        case "7": restart(); break;
        default:
            console.log("Unhandled hotkey: " + key);
            break;
    }
});

</script>

Thank you very much for the modification. I'll chek it and inform you