Revision [14069]

This is an old revision of SlideshowGallery made by YodaHome on 2006-05-02 20:58:36.

 

SlideshowGallery


I've made a first version of the AjaxGallery using some minor Java Script techniques. I always wanted to have a gallery that offers a slideshow so I can quickly browse through the pictures of one gallery. Some time ago I stumbled about a really neat javascript that does just that but the list of image files was hardcoded into it. So I took this and extended it with php. I think this combination is really cool.

What it can do


- Creates a table with thumbnails from any directory that contains image files (jpg, gif and png)
- generates the thumbnails and saves them in a .thumbs directory
- on click opens a new window with the slideshow script
- you can use more than one gallery on one wikka page (sounds trivial but it took me some time to make this work)

slideshow script:

- automatically zooms to the size of the image or to the size of the window (if the image is larger)
- lets you click through the images manually or continues automatically after a few seconds

Demo


See it work on http://yodahome.de/wiki/MyPics

Prerequisites / Installation


Your server needs GD support for PHP installed for the thumbnails. Furthermore this extension depends on the JavaScript library called Prototype. prototype.js needs to be placed in a subdirectory scripts in the action directory.

All in all there should xxx files on new your wikka installation:

wikka/actions

gallery.php (you may choose another name for the action)
slideshow.php
grafx.php
ajax-slideshowSmall.css (you might wanna place this elsewhere, just change the path in slideshow.php)

wikka/actions/scripts

prototype.js
ajax-slideshow.js
net.js

Furthermore there are some images which I placed in a subdirectory images (I know, very creative).

I've created a handy zip file where all files should be included. Of course you also need pictures located in a seperate directory.

This should work in any Browser with basic JavaScript. It's been tested in Mozilla Firefox 1.5, Internet Explorer 6 and 7 (beta), Opera 8 Konqueror 3.5 and I think someone even tried it in Safari (probably latest version as of March 2006).
On Opera 9 Beta the switches at the sides to go forward and backward do not appear. Apart from that it works. Any further experiences are much appreciated.

Some Source Code


actions/gallery.php

<?php

require_once './actions/grafx.php';

//framework output
$dir = $vars['dir'];

//$dir = $vars['dir']; // First thing to do, I suppose is to retrieve all of the filenames in the directory
    if ( !is_dir($dir) )
        {
        $output = "That directory does not exists (or it could be a file!)";
        } else
        { // Does the thumbs directory exist? If not then make it...
        $thumbdir = $dir."/.thumbs";
        if ( true !== file_exists($thumbdir) )
        {
        mkdir($thumbdir);
        }
        $files = GetFileList($dir);
        // Right, with that done, we need to see if a thumb exists for each pic
        // If it doesn't, then we gots to create one!
        // Thumbs will be called tn_filename.jpg
        $position = 0;
        $counter = 1;
        $output .= "<center><table cellpadding=\"0\" cellspacing=\"5\" width=\"75%\"> <tr>";
        foreach ( $files as $filename )
            {
            $thumbname = "tn_".$filename;
            if ( true !== file_exists($thumbdir."/".$thumbname) )
                {
                createthumb($dir,$filename);
                }
            $output .= "<td><a style=\"border:0px;\" href=\"./actions/slideshow.php?path=../$dir#$counter\" onclick=\"openwindow(this.href); return false\"><img src=\"$thumbdir/$thumbname\" border=\"0px\" style=\"border : 0px;\"/></a></td>\n";
            $position += 1; $counter += 1;
            if ( $position == "4" )
                {
                $output .= "</tr>";
                $position = 0;
                $output .= "<tr>";
                }
            }
            $output .= "</tr>";
        }
        $output .= "</table></center>"; print($output);


?>


slideshow.php (the javascript in here is written by Scott Upton)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>

<title>AJAX Slideshow</title>

<link href="ajax-slideshowSmall.css" rel="stylesheet" type="text/css" />
<script src="scripts/ajax-slideshow.js" type="text/JavaScript" charset="utf-8"></script>

    <script type="text/JavaScript" charset="utf-8">
    // <![CDATA[
   
    // -----------------------------------------------------------------------------------
    //
    // This page coded by Scott Upton
    // http://www.uptonic.com | http://www.couloir.org
    //
    // This work is licensed under a Creative Commons License
    // Attribution-ShareAlike 2.0
    // http://creativecommons.org/licenses/by-sa/2.0/
    //
    // Associated API copyright 2002, Travis Beckham (www.squidfingers.com)
    //
    // -----------------------------------------------------------------------------------
    // --- version date: 04/30/05 ------------------------------------------------------
   
    var photoDir = "<?php echo $_GET['path']?>"; // Location of photos for gallery
    var borderSize = 6;  // = 2x CSS border size
   
    // get current photo id from URL
    var thisURL = document.location.href;
    var splitURL = thisURL.split("#");
    var photoId = splitURL[1] - 1;
    //var photoId = 0;
   
    // if no id in query string then set to 0
    photoId = (!photoId)? 0:photoId;
       
    // Define each photo's name, height, width, and caption
    var photoArray = new Array(
        // Source, Width, Height, Caption
       
<?php
function GetFileList($dirname, $ext = FALSE)
    {
    if(!$ext) //EXTENSIONS OF FILE YOU WANNA SEE IN THE ARRAY
    $ext = array("jpg", "png", "jpeg", "gif");
    $files = array();
    $dir = opendir($dirname);
    while(false !== ($file = readdir($dir)))
        { //GET THE FILES ACCORDING TO THE EXTENSIONS ON THE ARRAY
        for ($i = 0; $i < count($ext); $i++)
            {
            if (eregi("\.". $ext[$i] ."$", $file))
                { $files[] = $file; }
            }
        } //CLOSE THE HANDLE
        closedir($dir); //ORDER OF THE ARRAY
        sort($files);
        return $files;
    }      
   
$dir = $_GET['path'];
    if ( !is_dir($dir) )
        {
        echo "That directory ($dir) does not exists (or it could be a file!)";
        } else
        {
        $files = GetFileList($dir);
        $count = 1;
       
        foreach ( $files as $filename )
            {
            $size = getimagesize($dir.$filename);
            if ($count>=count($files)) {
                echo "new Array(\"".$filename."\", \"".$size[0]."\", \"".$size[1]."\", \"\")\n";
            } else echo "new Array(\"".$filename."\", \"".$size[0]."\", \"".$size[1]."\", \"\"),\n";
            $count=$count+1;
            }
        }
   
?>
);
   
    // Number of photos in this gallery
    var photoNum = photoArray.length;
   
    // Create access to 'Detect' object and a place to put instances of 'HTMLobj'
    API = new Detect();
   
    // CREATE INSTANCES & LOAD
    loadAPI = function(){
        // Instantiate HTMLobj
        API.Container       = new HTMLobj('Container');
        API.Photo           = new HTMLobj('Photo');
        API.PhotoContainer  = new HTMLobj('PhotoContainer');
        API.LinkContainer   = new HTMLobj('LinkContainer');
        API.PrevLink        = new HTMLobj('PrevLink');
        API.NextLink        = new HTMLobj('NextLink');
        API.CaptionBlock    = new HTMLobj('CaptionBlock');
        API.Counter         = new HTMLobj('Counter');
        API.Caption         = new HTMLobj('Caption');
        API.LoadImg         = new HTMLobj('LoadImg');
       
        // Show initial photo
        cyclePhoto(photoId);
    }
    onload = loadAPI;
   
    var h,w;
    function get_viewport ()
    {
        if (self.innerHeight) // all except Explorer
            {
                w = self.innerWidth;
                h = self.innerHeight;
            }
        else if (document.documentElement && document.documentElement.clientHeight)
    // Explorer 6 Strict Mode
            {
                w = document.documentElement.clientWidth;
                h = document.documentElement.clientHeight;
            }
        else if (document.body) // other Explorers
            {
                w = document.body.clientWidth;
                h = document.body.clientHeight;
            }
    }
   
    // Fade in photo when it is loaded from the server
    initFade = function(){
        // Show PhotoContainer again
        API.PhotoContainer.show();
       
        // Be certain the tween is complete before fading, too
        var fade_timer = setInterval('startFade()', 1000);
                       
        // Fade photo in when ready and clear listener
        startFade = function(){
            if(API.Container._tweenRunning == false){
                clearInterval(fade_timer);
               
                // Be certain fade is done running before allowing next/previous links to work
                // This avoids rapid fade-in when users click next/previous links in quick succession
                var adv_timer = setInterval('permitNextPrev()', 500);
               
                // Permit next/previous links to function normally when fade is completed
                permitNextPrev = function(){
                    if(API.Photo._fadeRunning == false){
                        clearInterval(adv_timer);
                       
                        // Only show links if there is more than one photo in array
                        if(photoNum > 1){
                            API.LinkContainer.displayShow();
                            document.getElementById('NextLink').onclick = nextPhoto;
                            document.getElementById('PrevLink').onclick = prevPhoto;
                        }
                    } else {
                        return;
                    }
                }
                // Swap out loading animation to spare CPU cycles when hidden anyway
                API.LoadImg.setSrc("images/slideshow/start.gif");
               
                // Show caption again
                //API.CaptionBlock.show();
               
                // Fade photo in
                API.Photo.fadeIn(0,15,33);
            } else {
                return;
            }
        }
    }
   
    // Prevent next/previous
    falsify = function(){
        return false;
    }
   
    // Go to next photo
    nextPhoto = function(){
        // Go to next photo
        if(photoId == (photoArray.length - 1)){
            photoId = 0;
        } else {
            photoId++;
        }
        cyclePhoto(photoId);
    }
   
    // Go to previous photo
    prevPhoto = function(){
        // If at start, go back to end
        if(photoId == 0){
            photoId = photoArray.length - 1;
        } else {
            photoId--;
        }
        cyclePhoto(photoId);
    }
   
    // Alter class of elements
    changeElementClass = function(objId,setClass) {
        document.getElementById(objId).className = setClass;
    }
   
    // Function to load subsequent photos in gallery
    cyclePhoto = function(photoId){
               
        // Swap in loading animation
        API.LoadImg.setSrc("images/slideshow/loading_ani2.gif");
       
        // Hide link container if it is not already hidden
        API.LinkContainer.displayHide();
       
        // Hide photo container and caption temporarily
        API.Photo.hide();
        API.Photo.setOpacity(0);
        API.CaptionBlock.hide();
       
        // Get dimensions of photo
        var wNew = photoArray[photoId][1];
        var hNew = photoArray[photoId][2];
        get_viewport();
        w=w-30;h=h-30;
        if (wNew>w && hNew>h) {
        if (wNew>hNew) {
                hNew = (w * hNew) / wNew;
                wNew = w;
                if (hNew>h)
                    {
                        wNew = (h * wNew) / hNew;
                        hNew = h;
                    }
            } else {
                wNew = (h * wNew) / hNew;
                hNew = h;
               
           
            }
       
        }      
       
        // Start tween on a delay
        var wCur = API.Container.getWidth() - borderSize;
        var hCur = API.Container.getHeight() - borderSize;
       
        // Begin tweening on a short timer
        setTimeout('API.Container.tweenTo(easeInQuad, ['+wCur+', '+hCur+'], ['+wNew+','+hNew+'], 7)',500);
        setTimeout('API.LinkContainer.sizeTo('+wNew+','+hNew+')',500);
        setTimeout('API.PrevLink.sizeTo('+wNew/2+','+hNew+')',500);
        setTimeout('API.NextLink.sizeTo('+wNew/2+','+hNew+')',500);
        //setTimeout('API.CaptionBlock.sizeTo('+wNew+',18)',500);
        setTimeout('API.CaptionBlock.sizeTo(0,0)',500);
   
        // Get new photo source
        var newPhoto = photoDir + photoArray[photoId][0];
       
        // Set source, width, and height of new photo
        API.Photo.setSrc(newPhoto);    
        API.Photo.sizeTo(wNew,hNew);
       
        // Set links to new targets based on photoId
        API.NextLink.setHref("#" + (photoId+1));
        API.PrevLink.setHref("#" + (photoId+1));
        //API.Counter.setInnerHtml((photoId+1)+" of "+photoNum+" |");
        //API.Caption.setInnerHtml(photoArray[photoId][3]);
        API.Counter.setInnerHtml("");
        API.Caption.setInnerHtml("");
       
        // Event listeners for onload and onclick events
        document.getElementById('Photo').onload = initFade;
       
        // Block next/previous links until permitNextPrev() has fired
        document.getElementById('NextLink').onclick = falsify;
        document.getElementById('PrevLink').onclick = falsify;
    }
   
     self.setTimeout('setInterval("nextPhoto()", 15000)', 15000)
        //var ourInterval = setInterval('nextPhoto()', 10000);
    // ]]>
    </script>

</head>

<body bgcolor="#FFFFFF"  >
<!-- resizable container -->
<div id="Container">
<div id="LinkContainer">
<a href="#" id="PrevLink" onfocus="this.blur();" accesskey="[" title="&laquo; Previous Photo" class="plainlink"><span>Previous</span></a><a href="#" id="NextLink" onfocus="this.blur();" accesskey="]" title="Next Photo &raquo;" class="plainlink"><span>Next</span></a>
</div>
<div id="PhotoContainer"><img id="Photo" src="images/7sm.gif" alt="" width="50" height="50" /></div>
<div id="LoadContainer"><img id="LoadImg" src="images/loading_ani2.gif" alt="Loading..." width="48" height="54" /></div>
</div>

<!-- counter and caption -->
<p id="CaptionBlock"><span id="Counter"></span> <span id="Caption"></span></p>

</div>

</body>
</html>


grafx.php

<?php

function GetFileList($dirname, $ext = FALSE)
    {
    if(!$ext) //EXTENSIONS OF FILE YOU WANNA SEE IN THE ARRAY
    $ext = array("jpg", "png", "jpeg", "gif");
    $files = array();
    $dir = opendir($dirname);
    while(false !== ($file = readdir($dir)))
        { //GET THE FILES ACCORDING TO THE EXTENSIONS ON THE ARRAY
        for ($i = 0; $i < count($ext); $i++)
            {
            if (eregi("\.". $ext[$i] ."$", $file))
                { $files[] = $file; }
            }
        } //CLOSE THE HANDLE
        closedir($dir); //ORDER OF THE ARRAY
        sort($files);
        return $files;
    }      

//thumbnail: generate thumbnails  http://www.alt-php-faq.org/local/105/
  function createthumb($dir,$filename)
{  
    $thumb_path = $dir."/.thumbs/tn_".$filename;
    $thumb_width = 100;
    if(strtolower(substr($filename,strlen($filename)-4,strlen($filename))) == ".png"){
        $src_img = imagecreatefrompng("$dir/$filename");
    }elseif(strtolower(substr($filename,strlen($filename)-4,strlen($filename))) == ".jpg" || substr($filename,strlen($filename)-4,strlen($filename)) == "jpeg" ){
        $src_img = imagecreatefromjpeg("$dir/$filename");
    }elseif(strtolower(substr($filename,strlen($filename)-4,strlen($filename))) == ".gif"){
        $src_img = imagecreatefromgif("$dir/$filename");
    }
    $origw=imagesx($src_img);
    $origh=imagesy($src_img);
    $new_w = $thumb_width;
    $diff=$origw/$new_w;
    //$new_h=$new_w;
    $new_h=$origh/$diff;

    // the folowing line is commented out to get a better thumbnail,  but the imagecreatetruecolor only works with gd 2 or higher
    //$dst_img = imagecreate($new_w,$new_h);
    $dst_img = imagecreatetruecolor($new_w,$new_h);
    imagecopyresized($dst_img,$src_img,0,0,0,0,$new_w,$new_h,imagesx($src_img),imagesy($src_img));

    imagejpeg($dst_img, "$thumb_path");
    return true;
}

echo '<script type="text/javascript">
function openwindow(adresse)
{
viewer = window.open(adresse,"viewer","width=800,height=600,scrollbars=no,status=no");
viewer.focus();
}
</script>'
;

?>


As usual, if you encounter any errors during usage or by reading the code please let me know.


CategoryUserContributions
There are 9 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki