Hagith
6/20/2014 - 11:30 AM

Simple gallery with continuous scroll

Simple gallery with continuous scroll

<?php
define('BASE_PATH', '/home/rgalka/Pictures');
$image = @$_GET['image'];
if (!empty($image)) {
    $file = BASE_PATH . '/' . $image;
    if (!is_file($file)) {
        echo "Sorry, no file matching request";
        exit;
    }

    header('Content-type:' . mime_content_type($file));
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

function getDirectories($dir) {
    $ret = array();
    foreach (new DirectoryIterator($dir) as $fileInfo) {
        if($fileInfo->isDot() || $fileInfo->isFile())
            continue;
        $ret[] = $fileInfo->getFilename();
    }
    return $ret;
}

function getImages($dir, $page = 0, $perPage = 10) {
    $images = array();
    foreach (new DirectoryIterator($dir) as $fileInfo) {
        if($fileInfo->isDir())
            continue;
        $images[] = $fileInfo->getFilename();
    }
    return array_slice($images, $perPage * $page, $perPage);
}
?>

<html>
<head>
    <title>Infinite gallery</title>
    <style type="text/css">
    html, body {
        margin: 0;
        padding: 0;
    }
    body {
        padding: 10px;
    }
    .container {
        width: 1000px;
        margin: 0 auto;
    }
    img {
        width: 100%;
        min-height: 600px;
        margin-bottom: 10px;
        border-radius: 10px;
        -webkit-box-shadow: 0px 0px 18px 0px rgba(0,0,0,0.75);
        -moz-box-shadow: 0px 0px 18px 0px rgba(0,0,0,0.75);
        box-shadow: 0px 0px 18px 0px rgba(0,0,0,0.75);
        border: 1px solid #000;

        opacity: 1;
        transition: opacity 1s linear;
    }
    img.empty {
        opacity: 0;
    }
    </style>

</head>
<body>
    <div class="container">
        <?php
        error_reporting(E_ALL);
        ini_set('display_errors', 1);

        $dir = @$_GET['dir'];
        $page = (int)@$_GET['page'];

        if (empty($dir)) {
            foreach (getDirectories(BASE_PATH) as $item) {
                echo '<a href="?dir=' . $item . '">' . $item . '</a><br>';
            }
        } else {
            echo '<div id="images">';
            foreach (getImages(BASE_PATH . '/' . $dir, $page) as $k => $image) {
                if ($k < 2) {
                    echo '<img src="?image=' . $dir . '/' . $image . '">';
                } else {
                    echo '<img class="empty" data-src="?image=' . $dir . '/' . $image . '">';
                }
            }
            echo '</div>';
        }
        ?>
    </div>

    <script type="text/javascript">
        (function () {
            var page = 0,
                viewportHeight = window.innerHeight,
                pageHeight = document.documentElement.clientHeight,
                scrollPosition,
                loadLock = false,
                xmlhttp = new XMLHttpRequest();

            function load() {
                page++;
                var url = window.location.search + '&page=' + page;

                xmlhttp.open('GET', url, true);
                xmlhttp.send();
                xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4) {
                        var div = document.createElement('div');
                        div.innerHTML = xmlhttp.responseText;
                        var images = div.querySelectorAll('#images img');

                        if (images.length == 0) {
                            return;
                        }

                        var cont = document.querySelector('#images');
                        for (var i = 0, max = images.length; i < max; i++) {
                            if (images[i].src) {
                                images[i].setAttribute('data-src', images[i].getAttribute('src'));
                                images[i].removeAttribute('src');
                            }
                            cont.appendChild(images[i]);
                        }
                        loadLock = false;
                    }
                };
            };

            function onScroll() {
                pageHeight = document.documentElement.clientHeight
                scrollPosition = window.pageYOffset;

                if ((pageHeight - viewportHeight - scrollPosition) < viewportHeight && !loadLock) {
                    loadLock = true;
                    load();
                }
            };
            window.addEventListener('scroll', onScroll);

            var checkLock = false;

            function checkImgVisibility () {
                if (checkLock) {
                    return;
                }
                checkLock = true;

                var images = document.querySelectorAll('#images img');

                for (var i = 0, max = images.length; i < max; i++) {
                    if (images[i].src) {
                        continue;
                    }

                    var windowLeft = window.scrollX,
                        windowTop = window.scrollY,
                        windowHeight = window.innerHeight,
                        bodyRect = document.body.getBoundingClientRect(),
                        imgRect = images[i].getBoundingClientRect(),
                        left = imgRect.left,
                        top = imgRect.top - bodyRect.top;

                    if (top + images[i].height >= windowTop && top <= windowTop + windowHeight) {
                        images[i].setAttribute('src', images[i].getAttribute('data-src'));
                        images[i].removeAttribute('data-src');
                        images[i].addEventListener('load', function (e) {
                            e.srcElement.classList.remove('empty');
                        });
                    }
                }

                checkLock = false;
            }

            window.addEventListener('scroll', checkImgVisibility);
            window.addEventListener('resize', checkImgVisibility);
            setTimeout(checkImgVisibility, 200);
        }());
    </script>
</body>
</html>