Продвинутая галерея на PHP и jQuery
by Вредный • 23.02.2010 • jQuery, php, программирование • Комментарии [3]
Сегодня мы с вами разработаем небольшую галерею, у которой будет подобие админки с возможностью добавления новых и удалением имеющихся фотографий. Самое интересное в этой галерее будет возможность задать размеры миниатюры в реальном времени, сразу наблюдая за изменениями. Код писался на скорую руку, поэтому ни о какой безопасности и юзабилити речь не идет. Но, если кому покажется интересным создания галереи с нуля, легко сможет добавить недостающий функционал и расширить уже имеющийся.
Также вы можете ознакомиться с заметкой Создание миниатюр на PHP
Создание админки
Для начала создадим файл config.php, в котором будем хранить некоторые конфигурационные данные. В первую очередь это секретной слово, которое поможет нам обезопаситься от посторонних глаз. У меня галерея располагается в папке http://localhost/resizilka. Исходя из этого и будет организован конфиг.
1 2 3 4 5 6 | <? php $galleryFolder = 'gallery'; $thumbsFolder = 'gallery/thumbs'; $host = 'http://localhost/resizilka'; $secretKey = 'fsdfs432fxD'; ?> |
$galleryFolder — папка на сервере, где будут располагаться изображения.
$thumbsFolder — папка, в которой будут храниться миниатюры.
$host — для вывода картинок в галерее.
$secretKey — своего рода пароль, при вводе которого мы попадаем в админку.
Теперь о админке, которая будет состоять из одного файла. Конечно, если бы их было больше, можно было упростить структуру.
В начале файла нам понадобится подключить конфигурационный файл и открыть сессию (главное, чтобы до открытия сессии ничего не выводилось, а то вылезет ошибка). Файл admin.php
1 2 3 4 5 6 7 8 9 10 | <?php require_once 'config.php'; session_start(); if ($_SESSION['secretkey'] != 'passed') { if ($_GET['secret'] != $secretKey) { die('access denied'); } else { $_SESSION['secretkey'] = 'passed'; } } ?> |
Для того, чтобы войти в админку нам нужно проследовать по адресу http://localhost/resizilka/admin.php?secret=fsdfs432fxD (в конце адреса ключ из конфигурационного файла)
Дальше вставим html-заголовки и подключим нужные стили и скрипты (помимо jQuery используется плагин Resizable). Скачать их и все файлы проекта, вы можете по ссылке в конце заметки.
1 2 3 4 5 6 7 8 9 10 11 | < !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" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/interface.js"></script> <link rel="stylesheet" type="text/css" href="styles/main.css" /> </head> <body> |
Так как у нас все располагается в одном файле, нам нужна проверка не загружен ли файл, если да, то создаем миниатюру, если нет, то выводим только форму для добавления новых и таблицу с крестиком для удаления имеющихся.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php if(!isset($_FILES['filename'])) {?> <h2>Загрузка файлов на сервер</h2> <form method="post" enctype="multipart/form-data" action="admin.php"> <input type="file" name="filename" /> <input type="submit" value="Загрузить" /> </form> <h2>Имеющиеся фотки</h2> <?php $images = scandir($thumbsFolder); echo "<table cellpadding=\"10\">"; unset ($images[0]); unset ($images[1]); foreach ($images as $image) { echo "<tr><td><img src=\"" . $host . '/' . $thumbsFolder . '/' . $image . "\" /></td>\n"; echo "<td><a href=$host/erase.php?ss=$image>x</a></td></tr>"; } echo ""; ?> |
unset‘ами мы исключаем вывод . и ..
Таблица представляет из себя строки из картинки и крестика, при нажатии на который мы удаляем картинку, отдавая ее в руки скрипту erase.php Текст файла для удаления:
1 2 3 4 5 | <?php require_once 'config.php'; unlink($thumbsFolder . '/' . $_GET['ss']); header("Location: $host/admin.php"); ?> |
После удаления переходим на главную страницу админки. За это отвечает редирект.
Теперь ветка алгоритма, если мы что-то загрузили на сервер в файле admin.php
1 2 3 4 5 6 7 8 9 10 11 12 | <?php } else { echo $_FILES['filename']['type']; $picFilename = $_FILES['filename']['name']; if (copy($_FILES['filename']['tmp_name'], $galleryFolder . '/' . $picFilename)) { $picPath = $galleryFolder . '/' . $picFilename; $picData = getimagesize($picPath); $picWidth = $picData[0]; $picHeight = $picData[1]; echo $picWidth . ' x ' . $picHeight; ?> |
Т.к. галерея делалась для себя, здесь много debug-информации. Например, тут выводятся размеры картинки, которые мы будет использовать далее.
Сразу подготовим функцию для ресайзинга, которая в качестве параметров принимает картинку-источник и картинку-назначение, координаты левого верхнего угла и размеры. Это и будет наш файл cutting.php, к которому мы будем обращаться посредством AJAX-запроса с помощью jQuery.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <?php require_once 'config.php'; $src = $galleryFolder . '/' . $_GET['src']; $dest = $thumbsFolder . '/' . time() . $_GET['src']; $x = $_GET['x']; $y = $_GET['y']; $width = $_GET['width']; $height = $_GET['height']; imageCutting($src, $dest, $x, $y, $width, $height); function imageCutting($src, $dest, $x, $y, $width, $height, $rgb = 0xffffff) { if(!file_exists($src)) { echo "$ src not exist"; return FALSE; } $size = getimagesize($src); if ($size === FALSE) { echo "cannot get image size"; return FALSE; } $format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1)); $icFunc = 'imagecreatefrom' . $format; if (!function_exists($icFunc)) { echo "function does not exist"; return FALSE; } $isrc = $icFunc($src); $idest = imagecreatetruecolor($width, $height); imagefill($idest, 0, 0, $rgb); imagecopyresampled($idest, $isrc, 0, 0, $x, $y, $width, $height, $width, $height); imagejpeg($idest, $dest, 80); imagedestroy($isrc); imagedestroy($idest); echo "all done <br /><b>" . $dest . '</b><br /> was created'; return TRUE; } ?> |
Теперь перейдем к разметке и программированию на стороне клиента. Т.к. почти весь функционал у нас находится в одном файле, нам будет намного удобнее передавать значения некоторых переменных в JavaScript.
Продолжим кропотать над index.php. Добавим немного разметки и само изображение, чтобы видно было из чего мы хотим сделать миниатюру.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <div id="container" style="position: relative; width: <?php echo $picWidth; ?>px; height: <?php echo $picHeight; ?>px;"> <img src="<?php echo $picPath; ?/>" /> <div id="resizeMe"> <div id="resizeSE"></div> <div id="resizeE"></div> <div id="resizeNE"></div> <div id="resizeN"></div> <div id="resizeNW"></div> <div id="resizeW"></div> <div id="resizeSW"></div> <div id="resizeS"></div> </div> </div> <br /> <div style="position: absolute; right: 0; top: 0; width: 200px;"> <b>Позиция</b> <br /> x: <span id="left"></span> y: <span id="top"></span> <br /> <button>Закончить</button> <div id="info"></div> </div> |
1 | id="resizeMe" |
и все вложенные в него элементы отвечают за квадратик с рамкой и маркерами для ресайза. Добавим немного уличной магии в виде JavaScript.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | <script type="text/javascript"> var pic_x, pic_y; $(document).ready( function() { $('button').click(function() { if (pic_x == undefined) pic_x = 0; if (pic_y == undefined) pic_y = 0; var q; q = 'src=<?php echo $picFilename; ?>&'; q = q + 'x=' + pic_x; q = q + '&y=' + pic_y; q += '&width=200'; q += '&height=150'; $('div#info').load('cutting.php?' + q); }) $('#resizeMe').Resizable( { minWidth: 200, minHeight: 150, maxWidth: 200, maxHeight: 150, minTop: 1, minLeft: 1, maxRight: <?php echo $picWidth; ?>, maxBottom: <?php echo $picHeight; ?>, dragHandle: true, onDrag: function(x, y) { pic_x = x; pic_y = y; $('#left').html(x + 'px'); $('#top').html(y + 'px'); }, handlers: { se: '#resizeSE', e: '#resizeE', ne: '#resizeNE', n: '#resizeN', nw: '#resizeNW', w: '#resizeW', sw: '#resizeSW', s: '#resizeS' }/*, onResize : function(size, position) { $('#left').html((position.left-50)+'px'); $('#top').html((position.top-50)+'px'); $('#width').html(size.width); $('#height').html(size.height); }*/ } ) } ); </script> |
Во второй строчке которого мы объявляем переменные, чтобы хранить в них координаты левого верхнего угла миниатюры. При нажатии на кнопку в 6 строке мы собираем параметры в одну строку и отправляем с помощью jQuery скрипту cutting.php, получая при этом какой-либо ответ без перезагрузки страницы. Если вы хотите, чтобы имелась возможность ресайзить квадратик, нужно задать отличные величины в строчках 20-23, раскомментировать строки 42-48 и в строках 14 и 15 передавать ширину и высоту соответственно.
Главная страница галереи
Осталось только сделать вывод картинок, которые находятся в папке миниатюр (в config.php за эту папку отвечает переменная $thumbsFolder).
Это и будет наш index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf8" /> <script type="text/javascript" src="js/jquery.js"></script> <link rel="stylesheet" type="text/css" href="styles/main.css" /> </head> <body> <?php require_once 'config.php'; $images = scandir($thumbsFolder); echo "<table cellpadding=10>"; unset ($images[0]); unset ($images[1]); foreach ($images as $image) { if (($i % 3 == 0) && ($i!=0)) echo "<tr>"; if ($i == 0) echo "</tr><tr>"; echo "<td><img src=\"" . $host . '/' . $thumbsFolder . '/' . $image . "\" /></td>\n"; $i++; } if ($i % 3 != 0) echo "</tr>"; ?> </body> </html> |
В этом файле мы всего лишь выводим наши миниатюры в таблице в три столбца.
Эта несложная в реализации галерея имеет право на существование, если ее довести до ума и продумать дизайн. Но это уже все на ваше усмотрение.
