New plugin for balanced height thumbnails
authorBaptiste CLÉMENT <batoche@free.fr>
Sat, 17 Aug 2013 14:27:34 +0000 (16:27 +0200)
committerMarc MAURICE <marc-bizou@pub.positon.org>
Sat, 17 Aug 2013 14:27:34 +0000 (16:27 +0200)
plugins/balanced/before_content.php [new file with mode: 0644]
plugins/balanced/functions.php [new file with mode: 0644]
plugins/balanced/head.php [new file with mode: 0644]
plugins/balanced/scripts.js [new file with mode: 0644]
plugins/balanced/style.css [new file with mode: 0644]

diff --git a/plugins/balanced/before_content.php b/plugins/balanced/before_content.php
new file mode 100644 (file)
index 0000000..63cbb11
--- /dev/null
@@ -0,0 +1 @@
+<div id="thumbsize" style="visibility:hidden"><?php echo THUMB_SIZE ?></div>
diff --git a/plugins/balanced/functions.php b/plugins/balanced/functions.php
new file mode 100644 (file)
index 0000000..9464423
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+function getPreview($imgFile, $maxSize = THUMB_SIZE)
+{
+        # example: data/myalbum/100.mypic.jpg
+        $newImgFile = DATA_DIR."/".dirname($imgFile)."/".$maxSize.".".basename($imgFile);
+
+        # if the preview is a symlink, image is already good sized
+        if (is_link($newImgFile)) return $imgFile;
+
+        if (! is_file($newImgFile))
+        {
+                # this tels the template to flush output after displaying previews
+                $GLOBALS["generating"] = true;
+
+                # reset script time limit to 20s (wont work in safe mode)
+                set_time_limit(20);
+
+                $ext = strtolower(substr($imgFile, -4));
+                if ($ext == ".jpg")
+                        $img = imagecreatefromjpeg($imgFile);
+                else
+                        $img = imagecreatefrompng($imgFile);
+
+                $w = imagesx($img);
+                $h = imagesy($img);
+                # if the image is already small, make a symlink, and return it
+                if ($w <= $maxSize and $h <= $maxSize) {
+                        imagedestroy($img);
+                        symlink($imgFile, $newImgFile);
+                        return $imgFile;
+                }
+
+                # config to allow group writable files
+                umask(DATA_UMASK);
+                # create the thumbs directory recursively
+                if (! is_dir(dirname($newImgFile))) mkdir(dirname($newImgFile), 0777, true);
+
+                //if ($w > $h) {
+                //      $newW = $maxSize;
+                //      $newH = $h/($w/$maxSize);
+                //} else {
+                        $newW = $w/($h/$maxSize);
+                        $newH = $maxSize;
+                //}
+
+                $newImg = imagecreatetruecolor($newW, $newH);
+
+                imagecopyresampled($newImg, $img, 0, 0, 0, 0, $newW, $newH, $w, $h);
+
+                if ($ext == ".jpg")
+                        imagejpeg($newImg, $newImgFile);
+                else
+                        imagepng($newImg, $newImgFile);
+
+                imagedestroy($img);
+                imagedestroy($newImg);
+        }
+
+        return $newImgFile;
+}
+
+
+?>
diff --git a/plugins/balanced/head.php b/plugins/balanced/head.php
new file mode 100644 (file)
index 0000000..44cca72
--- /dev/null
@@ -0,0 +1,9 @@
+<script language="javascript" src="../plugins/balanced/scripts.js"></script> 
+<script language="javascript">
+        window.onload = function(event) {
+                applyOptimalImagesSize();
+        }
+        window.onresize = function(event) {
+                applyOptimalImagesSize();
+        }
+</script>
diff --git a/plugins/balanced/scripts.js b/plugins/balanced/scripts.js
new file mode 100644 (file)
index 0000000..51eb4c6
--- /dev/null
@@ -0,0 +1,129 @@
+function applyOptimalImagesSize()\r
+{\r
+       var divimages = document.getElementsByClassName("image");\r
+       var images = new Array();\r
+       for(var i = 0 ; i < divimages.length ; ++i)\r
+       {\r
+               images.push(divimages[i].children[0].children[0]);\r
+       }\r
+       var bestHeight = parseInt(document.getElementById("thumbsize").textContent);\r
+       var newHList = getOptimalHeights(images, bestHeight);\r
+       for( var i = 0 ; i < images.length ; ++i)\r
+       {\r
+               images[i].height = newHList[i];\r
+       }\r
+}\r
+\r
+//Renvoi un tuple (with,height) de la taille de la surface d'affichage du navigateur\r
+function getClientWindowSize()\r
+{\r
+       var w = 0;\r
+       var h = 0;\r
+       \r
+        if (document.body)\r
+       {\r
+               w = (document.body.clientWidth);\r
+               h = (document.body.clientHeight);\r
+       }\r
+       else\r
+       {\r
+               w = (window.innerWidth);\r
+               h = (window.innerHeight);\r
+       }\r
+       \r
+       return [w,h];\r
+}\r
+\r
+//renvoie la hauteur optimal de chaque image pour occuper toute la largeur de la surface d'affichage\r
+function getOptimalHeights(images, bestHeight)\r
+{\r
+       var imageHeight = bestHeight;\r
+       var originalSizes = getAllImageSizesForHeight(images, imageHeight);\r
+       var clientSize = getClientWindowSize();\r
+       var newHeights = new Array();\r
+       var allWidth = new Array();\r
+       for(var i = 0 ; i < originalSizes.length ; ++i)\r
+       {\r
+               allWidth.push(originalSizes[i][0]);\r
+       }\r
+       \r
+       var splittedWidth = splitTab(allWidth, clientSize[0]);\r
+       for(var i = 0 ; i < splittedWidth.length ; ++i)\r
+       {\r
+               var sum = 15;\r
+               var ratiosum = 0.0;\r
+               for(var j=0 ; j< splittedWidth[i].length ; ++j)\r
+               { \r
+                       sum += splittedWidth[i][j] + 5; \r
+                       ratiosum += parseFloat(splittedWidth[i][j]) / parseFloat(imageHeight);\r
+               }\r
+               var deltaHeight = parseInt((clientSize[0] - sum) / parseFloat(ratiosum));\r
+               \r
+               var lastandtoobig = i == (splittedWidth.length-1) && sum < clientSize[0]/2;\r
+\r
+               for(var j=0 ; j< splittedWidth[i].length ; ++j)\r
+               { \r
+                       if(lastandtoobig)\r
+                       {\r
+                               newHeights.push(bestHeight);\r
+                       }\r
+                       else\r
+                       {\r
+                               newHeights.push(imageHeight + deltaHeight);\r
+                       }\r
+               }\r
+       }\r
+       return newHeights;\r
+}\r
+\r
+//donne la taille de toutes les images affichées\r
+function getAllImageSizes(images)\r
+{\r
+       var sizes = new Array();\r
+       for (var i = 0; i < images.length; i++) {\r
+               sizes.push([images[i].width, images[i].height]);\r
+       }\r
+       return sizes;\r
+}\r
+\r
+//donne la taille de toutes les images affichées, redimensionnées pour une hauteur donnée\r
+function getAllImageSizesForHeight(images, height)\r
+{\r
+       var sizes = new Array();\r
+       for (var i = 0; i < images.length; i++) {\r
+               sizes.push([images[i].width / (images[i].height / height) , height]);\r
+       }\r
+       return sizes;\r
+}\r
+\r
+\r
+\r
+\r
+//Renvoi un tableau de tableau, correspondant au découpage du tableau d'entrée découpé par tranche de MAX\r
+function splitTab(tab, max)\r
+{\r
+       var splitedTabs = [new Array()];\r
+       var sumSize = 15;\r
+       for (var i = 0; i < tab.length; i++)\r
+       {\r
+               element = tab[i];\r
+               \r
+               var total = sumSize + element + 5;\r
+               //regles arbirtaire de découpage en plus de total > max\r
+               //(parce que ca rend mieux visuellement)\r
+               //=> on ajoute la suite l'élement qui dépasse si sa taille fait moins d'1/4 de max\r
+               //=> ou si l'écart restant représente plus de la moitié de l'élément à ajouter\r
+               if((total > max && (sumSize > max ||(max - sumSize) > (element / 2) || element > max / 4)) || element >= max)\r
+               {\r
+                       splitedTabs.push(new Array());\r
+                       splitedTabs[splitedTabs.length - 1].push(element);\r
+                       sumSize = 16 + element + 4;\r
+               }\r
+               else\r
+               {\r
+                       splitedTabs[splitedTabs.length - 1].push(element);\r
+                       sumSize = total;\r
+               }\r
+       }       \r
+       return splitedTabs;\r
+}\r
diff --git a/plugins/balanced/style.css b/plugins/balanced/style.css
new file mode 100644 (file)
index 0000000..69bc4e1
--- /dev/null
@@ -0,0 +1,5 @@
+.image {
+        display: block;
+        width: auto;
+        height: auto;
+}