AjaxGallery
This action is actually only partly based on ajax techniques and is my first aproach to this kind of enhancements.
What it can do
- scans a certain directory for image files (jpg,png and gif) and creates thumbnails in subdirectory ./thumbs
- if you click on the thumbnails a fixed box will appear on screen and will dynamically load the picture
- fits the picture to the available screen size (picture is php-resized and therefore only as large as it is visible)
- you can freely place the top layer on your screen through editing the css definition, you may scroll the page underneath
- if you resize your window the page doesn't need to be reloaded but the pictures will fit the new size
What it cannot do (yet)
- it works well on latest Mozilla-based browsers (Firefox, Konqueror though the effects are missing, I assume Safari [testers welcome]) AND (finally) in IE but it doesn't work on any version of Opera and the box is not floating while you scroll on IE
- just one gallery per page though this will be the next thing I look into
- consider this an alpha version (though the JavaScript libraries used are considered very stable)
- the code is ugly
- there is no fallback for non-ajax browser but it makes sense to add this
Demo
See it work on http://yodahome.de/wiki/SandBox
Prerequisites / Installation
Your server needs GD support for PHP installed for the resizement work. Furthermore this extension depends on two JavaScript libraries: Prototype and script.aculo.us. They need to be placed in a subdirectory "scripts" in the wiki directory. Make sure you copy the .htaccess file from the action directory to this subdirectory!
For your convenience: scripts.zip (prototype 1.4.0 and script.aculo.us 1.5.3)
You need to add these style definitions to your stylesheet. Of course you can change them to suit you needs (size position etc).
#viewer {
position:absolute;
width:84%;
height:84%;
top:50px;
left:50px;
}
#viewer[id] {
position:fixed;
top:50px;
left:50px;
bottom:50px;
right:50px;
}
position:absolute;
width:84%;
height:84%;
top:50px;
left:50px;
}
#viewer[id] {
position:fixed;
top:50px;
left:50px;
bottom:50px;
right:50px;
}
Those two files need to be placed in the actions directory:
actions/ajaxgallery.php
<?php
if (isset($_GET['show'])) {
function thumb($source, $w, $h, $quality = 85)
{
/* Check for the image's exisitance */
if (!file_exists($source)) {
echo 'File does not exist!';
}
else {
$size = getimagesize($source); // Get the image dimensions and mime type
if ($size[0]>$w && $size[1]>$h) {
if ($size[0]>$size[1]) {
$newHeight = ($w * $size[1]) / $size[0];
$newWidth = $w;
if ($size[1]>$h)
{
$newWidth = ($h * $size[0]) / $size[1];
$newHeight = $h;
}
} else {
$newWidth = ($h * $size[0]) / $size[1];
$newHeight = $h;
}
} else { $newWidth = $size[0];$newHeight = $size[1]; }
$resize = imagecreatetruecolor($newWidth, $newHeight); // Create a blank image
/* Check quality option. If quality is greater than 100, return error */
if ($quality > 100) {
echo 'The maximum quality is 100. <br>Quality changes only affect JPEG images.';
}
else {
header('Content-Type: '.$size['mime']); // Set the mime type for the image
switch ($size['mime']) {
case 'image/jpeg':
$im = imagecreatefromjpeg($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original JPEG
imagejpeg($resize, '', $quality); // Output the new JPEG
break;
case 'image/png':
$im = imagecreatefrompng($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original PNG
imagepng($resize, '', $quality); // Output the new PNG
break;
case 'image/gif':
$im = imagecreatefromgif($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original PNG
imagegif($resize, '', $quality); // Output the new PNG
break;
}
imagedestroy($im);
}
}
}
# echo $_GET['picture'].$_GET['width'].$_GET['height'];
if (isset($_GET['createpic'])) thumb($_GET['picture'], $_GET['width'], $_GET['height']); else {
echo '<html><head></head><body>';
echo '<center><img src="'.$_SERVER['PHP_SELF'].'?picture='.$_GET['picture'].'&width='.$_GET['width'].'&height='.$_GET['height'].'&createpic=1&show=1" alt="Show Picture" align="center"></center>';
echo '</body></html>';
}
} else {
function GetFileList1($dirname, $extensoes = FALSE, $reverso = FALSE)
{
if(!$extensoes) //EXTENSIONS OF FILE YOU WANNA SEE IN THE ARRAY
$extensoes = 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($extensoes); $i++)
{
if (eregi("\.". $extensoes[$i] ."$", $file))
{ $files[] = $file; }
}
} //CLOSE THE HANDLE
closedir($dir); //ORDER OF THE ARRAY
if ($reverso)
{
rsort($files);
} else {
sort($files);
} return $files;
}
//thumbnail: generate thumbnails http://www.alt-php-faq.org/local/105/
function createthumb1($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;
}
//framework output
echo '<script type="text/javascript" src="./scripts/prototype.js"></script>
<script type="text/javascript" src="./scripts/scriptaculous.js"></script>
<script type="text/javascript">
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;
}
}
function load_picture(picture)
{
get_viewport();
var url = "./actions/show.php";
var pars = "picture=" + picture + "&width=" + (w-100) + "&height=" + (h-100);
var myAjax = new Ajax.Updater("viewer", url, { method: "get", parameters: pars,onComplete: showResponse});
//var myAjax = new Ajax.Updater("viewer", url, { method: "get", parameters: pars});
}
function showResponse(originalRequest)
{
Effect.toggle("viewer","appear");
}
</script>
<div style="display:none" id="viewer" onclick="Effect.toggle(\'viewer\',\'appear\');return false;"></div>';
$dir = $vars['dir'];
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 = GetFileList1($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 in a subdir.
// Thumbs will be called tn_filename.jpg
$position = 0;
$output .= "<center><table cellpadding=\"0\" cellspacing=\"5\" width=\"75%\"> <tr>";
foreach ( $files as $filename )
{
$thumbname = "tn_".$filename;
if ( true !== file_exists($thumbdir."/".$thumbname) )
{
createthumb1($dir,$filename);
}
$imageref = "javascript:load_picture('.$dir/$filename');";
$output .= "<td><a href=\"$imageref\"><img src=\"$thumbdir/$thumbname\" style=\"border : 0px;\"/></a></td>";
$position += 1;
if ( $position == "4" )
{
$output .= "</tr>";
$position = 0;
$output .= "<tr>";
}
}
$output .= "</tr>";
}
$output .= "</table></center>"; print($output);
}
?>
if (isset($_GET['show'])) {
function thumb($source, $w, $h, $quality = 85)
{
/* Check for the image's exisitance */
if (!file_exists($source)) {
echo 'File does not exist!';
}
else {
$size = getimagesize($source); // Get the image dimensions and mime type
if ($size[0]>$w && $size[1]>$h) {
if ($size[0]>$size[1]) {
$newHeight = ($w * $size[1]) / $size[0];
$newWidth = $w;
if ($size[1]>$h)
{
$newWidth = ($h * $size[0]) / $size[1];
$newHeight = $h;
}
} else {
$newWidth = ($h * $size[0]) / $size[1];
$newHeight = $h;
}
} else { $newWidth = $size[0];$newHeight = $size[1]; }
$resize = imagecreatetruecolor($newWidth, $newHeight); // Create a blank image
/* Check quality option. If quality is greater than 100, return error */
if ($quality > 100) {
echo 'The maximum quality is 100. <br>Quality changes only affect JPEG images.';
}
else {
header('Content-Type: '.$size['mime']); // Set the mime type for the image
switch ($size['mime']) {
case 'image/jpeg':
$im = imagecreatefromjpeg($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original JPEG
imagejpeg($resize, '', $quality); // Output the new JPEG
break;
case 'image/png':
$im = imagecreatefrompng($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original PNG
imagepng($resize, '', $quality); // Output the new PNG
break;
case 'image/gif':
$im = imagecreatefromgif($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original PNG
imagegif($resize, '', $quality); // Output the new PNG
break;
}
imagedestroy($im);
}
}
}
# echo $_GET['picture'].$_GET['width'].$_GET['height'];
if (isset($_GET['createpic'])) thumb($_GET['picture'], $_GET['width'], $_GET['height']); else {
echo '<html><head></head><body>';
echo '<center><img src="'.$_SERVER['PHP_SELF'].'?picture='.$_GET['picture'].'&width='.$_GET['width'].'&height='.$_GET['height'].'&createpic=1&show=1" alt="Show Picture" align="center"></center>';
echo '</body></html>';
}
} else {
function GetFileList1($dirname, $extensoes = FALSE, $reverso = FALSE)
{
if(!$extensoes) //EXTENSIONS OF FILE YOU WANNA SEE IN THE ARRAY
$extensoes = 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($extensoes); $i++)
{
if (eregi("\.". $extensoes[$i] ."$", $file))
{ $files[] = $file; }
}
} //CLOSE THE HANDLE
closedir($dir); //ORDER OF THE ARRAY
if ($reverso)
{
rsort($files);
} else {
sort($files);
} return $files;
}
//thumbnail: generate thumbnails http://www.alt-php-faq.org/local/105/
function createthumb1($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;
}
//framework output
echo '<script type="text/javascript" src="./scripts/prototype.js"></script>
<script type="text/javascript" src="./scripts/scriptaculous.js"></script>
<script type="text/javascript">
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;
}
}
function load_picture(picture)
{
get_viewport();
var url = "./actions/show.php";
var pars = "picture=" + picture + "&width=" + (w-100) + "&height=" + (h-100);
var myAjax = new Ajax.Updater("viewer", url, { method: "get", parameters: pars,onComplete: showResponse});
//var myAjax = new Ajax.Updater("viewer", url, { method: "get", parameters: pars});
}
function showResponse(originalRequest)
{
Effect.toggle("viewer","appear");
}
</script>
<div style="display:none" id="viewer" onclick="Effect.toggle(\'viewer\',\'appear\');return false;"></div>';
$dir = $vars['dir'];
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 = GetFileList1($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 in a subdir.
// Thumbs will be called tn_filename.jpg
$position = 0;
$output .= "<center><table cellpadding=\"0\" cellspacing=\"5\" width=\"75%\"> <tr>";
foreach ( $files as $filename )
{
$thumbname = "tn_".$filename;
if ( true !== file_exists($thumbdir."/".$thumbname) )
{
createthumb1($dir,$filename);
}
$imageref = "javascript:load_picture('.$dir/$filename');";
$output .= "<td><a href=\"$imageref\"><img src=\"$thumbdir/$thumbname\" style=\"border : 0px;\"/></a></td>";
$position += 1;
if ( $position == "4" )
{
$output .= "</tr>";
$position = 0;
$output .= "<tr>";
}
}
$output .= "</tr>";
}
$output .= "</table></center>"; print($output);
}
?>
actions/show.php
<?php
function generate($source, $w, $h, $quality = 85)
{
/* Check for the image's exisitance */
if (!file_exists($source)) {
echo 'File does not exist!';
}
else {
$size = getimagesize($source); // Get the image dimensions and mime type
if ($size[0]>$w && $size[1]>$h) {
if ($size[0]>$size[1]) {
$newHeight = ($w * $size[1]) / $size[0];
$newWidth = $w;
if ($size[1]>$h)
{
$newWidth = ($h * $size[0]) / $size[1];
$newHeight = $h;
}
} else {
$newWidth = ($h * $size[0]) / $size[1];
$newHeight = $h;
}
} else { $newWidth = $size[0];$newHeight = $size[1]; }
$resize = imagecreatetruecolor($newWidth, $newHeight); // Create a blank image
/* Check quality option. If quality is greater than 100, return error */
if ($quality > 100) {
echo 'The maximum quality is 100. <br>Quality changes only affect JPEG images.';
}
else {
header('Content-Type: '.$size['mime']); // Set the mime type for the image
switch ($size['mime']) {
case 'image/jpeg':
$im = imagecreatefromjpeg($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original JPEG
imagejpeg($resize, '', $quality); // Output the new JPEG
break;
case 'image/png':
$im = imagecreatefrompng($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original PNG
imagepng($resize, '', $quality); // Output the new PNG
break;
case 'image/gif':
$im = imagecreatefromgif($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original PNG
imagegif($resize, '', $quality); // Output the new PNG
break;
}
imagedestroy($im);
}
}
}
# echo $_GET['picture'].$_GET['width'].$_GET['height'];
if (isset($_GET['createpic'])) generate($_GET['picture'], $_GET['width'], $_GET['height']); else {
echo '<html><head><script type="text/javascript" src="./scripts/prototype.js"></script>
<script type="text/javascript" src="./scripts/scriptaculous.js"></script></head><body>';
echo '<div id="loading" style="position:absolute;top:0px;right:50%;background-color:gray;z-index:1;"><b>Loading...</b></div>';
echo '<center><img style="position:absolut;top:0px;left:0px;display:none;z-index:2;" id="img" src="'.$_SERVER['PHP_SELF'].'?picture='.$_GET['picture'].'&width='.$_GET['width'].'&height='.$_GET['height'].'&createpic=1" alt="Show Picture" align="center" onLoad="javascript:Effect.toggle(\'img\',\'appear\');Effect.toggle(\'loading\',\'appear\');return false;"></center>';
echo '</body></html>';
}
?>
function generate($source, $w, $h, $quality = 85)
{
/* Check for the image's exisitance */
if (!file_exists($source)) {
echo 'File does not exist!';
}
else {
$size = getimagesize($source); // Get the image dimensions and mime type
if ($size[0]>$w && $size[1]>$h) {
if ($size[0]>$size[1]) {
$newHeight = ($w * $size[1]) / $size[0];
$newWidth = $w;
if ($size[1]>$h)
{
$newWidth = ($h * $size[0]) / $size[1];
$newHeight = $h;
}
} else {
$newWidth = ($h * $size[0]) / $size[1];
$newHeight = $h;
}
} else { $newWidth = $size[0];$newHeight = $size[1]; }
$resize = imagecreatetruecolor($newWidth, $newHeight); // Create a blank image
/* Check quality option. If quality is greater than 100, return error */
if ($quality > 100) {
echo 'The maximum quality is 100. <br>Quality changes only affect JPEG images.';
}
else {
header('Content-Type: '.$size['mime']); // Set the mime type for the image
switch ($size['mime']) {
case 'image/jpeg':
$im = imagecreatefromjpeg($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original JPEG
imagejpeg($resize, '', $quality); // Output the new JPEG
break;
case 'image/png':
$im = imagecreatefrompng($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original PNG
imagepng($resize, '', $quality); // Output the new PNG
break;
case 'image/gif':
$im = imagecreatefromgif($source);
imagecopyresampled($resize, $im, 0, 0, 0, 0, $newWidth, $newHeight, $size[0], $size[1]); // Resample the original PNG
imagegif($resize, '', $quality); // Output the new PNG
break;
}
imagedestroy($im);
}
}
}
# echo $_GET['picture'].$_GET['width'].$_GET['height'];
if (isset($_GET['createpic'])) generate($_GET['picture'], $_GET['width'], $_GET['height']); else {
echo '<html><head><script type="text/javascript" src="./scripts/prototype.js"></script>
<script type="text/javascript" src="./scripts/scriptaculous.js"></script></head><body>';
echo '<div id="loading" style="position:absolute;top:0px;right:50%;background-color:gray;z-index:1;"><b>Loading...</b></div>';
echo '<center><img style="position:absolut;top:0px;left:0px;display:none;z-index:2;" id="img" src="'.$_SERVER['PHP_SELF'].'?picture='.$_GET['picture'].'&width='.$_GET['width'].'&height='.$_GET['height'].'&createpic=1" alt="Show Picture" align="center" onLoad="javascript:Effect.toggle(\'img\',\'appear\');Effect.toggle(\'loading\',\'appear\');return false;"></center>';
echo '</body></html>';
}
?>
Problems
This doesn't work that well with IE for several reasons: First IE 5+ doesn't understand the css option position:fixed which is needed to display the viewer correctly. I added a workaround for that but there are probably better ways to deal with it out there. Any help would be apreciated. I have not tested this with the IE 7 Beta, would anybody be so kind?
--Isn't the correct term used in Web Programming static instead of fixed, like when you want a background to stay still as you scroll down a page?
--GrahamKelly
- With IE8 just released, there's no real reason anymore to support IE <7, I think. Sorry, but we're talking about a browser almost a decade old (and being buggy beyond imagination without support of web standards long established) -- there are far better alternatives out there. Of course, I understand that there might be users, who cannot upgrade, e.g. because of company policies. But I think, those users might also be used to the fact, that their browser isn't supported that well. As all those Netscape Navigator 4.7 users cannot expect to have their browser supported anymore. AFAIK IE7+ supports position:fixed;. As for the nomenclature, CSS is not programming but just a simple set of definitions to apply. As is writing HTML no programming but marking up text. position:static; refers to the position in context to the surrounding content being static, while position:fixed; defines the element's position relative to the viewport (i.e. browser window most the time). MasinAlDujaili, 2009-05-13, 17:14 CEST
Discussion on Ajax in Wikka
CategoryUserContributions