Масштабирование изображений с использование Highslide JS

По просьбе товарища inecs пишу, как я реализовал масштабирование изображения с использованием highslide на фотожабе.ру. Поехали!

Для начало кратко о том, что это такое.
Highslide JS — это ПО с открытым исходным кодом на JavaScript, которое предлагает web 2.0 решение для всплывающих окон.
В общем говоря, это скрипт для создания модальных окон. В нашем случае он позволит нам делать кликабельные картинки с плавным увеличением размера. Более подробно о всех возможностях и тонкостях данного скрипта вы можете прочитать на highslide.com.

Итак, начнем интеграцию в ЛС.

Для того, чтобы иметь возможность увеличивать изображение, для начала, его надо иметь! Сейчас загрузка картинок работает по следующей схеме: Файл закачивается, уменьшается (если картинка не влазит в установленные «рамки») и сохраняется на сервере. Так что для того, чтобы увеличивать изображение мы должны его сохранить в первоначальном, большом размере. И для сего напишем следующую функцию


/**
 * Сохраняет файл на диск
 * @param string $sFileTmp
 * @param string $dir
 * @param string $sFileImg
 */

function func_save_img($sFileTmp,$dir,$sFileImg) {
	if(!is_dir(DIR_SERVER_ROOT.$dir))
	@func_mkdir(DIR_SERVER_ROOT,$dir);
	
	if(copy($sFileTmp,DIR_SERVER_ROOT.$dir.$sFileImg)) return true;
	
	return false;
}

которую добавим в файл /include/function.php (прям в конец, перед
?>
)
Суть этой функции проста. Она получает в качестве параметра путь ко временному файлу $sFileTmp, создает директорию $dir и копирует туда исходное изображение под именем $sFileImg.

Теперь наша задача состоит в том, чтобы сохранить сам файл после загрузки на сервер. При этом нужно проверить — изображение уменьшалось или нет? Какой смысл хранить один и тот же файл дважды? Зачем его увеличивать, если он не увеличится? Для этого в файл /include/ajax/uploadImg.php после каждой строчки (их там две)
$sFile=$sDirSave.'/'.$sFileImg;

вставим следующий код:
if(md5_file(DIR_SERVER_ROOT.$sFile) != md5_file($sFileTmp)  && func_save_img($sFileTmp,$sDirSave.'/big/',$sFileImg) ) $sBigFile = $sDirSave.'/big/'.$sFileImg;


Ах да! Мы забыли определить переменную $sBigFile.
После строчки
$sFile=null;
вставим
$sBigFile=null;

Что мы сделали? Мы сверили md5 суммы загруженного файла во временную директорию и сохраненного в папке /uploads/ Если они различны(файл изменен — видимо его масштабировали), то скопируем исходный файл в папку с уменьшенным/big/. Путь к нему держим в переменной $sBigFile. Теперь добавим ссылку на «большой» файл в html код изображения:

Находим строку
$sText.='>';
И после нее добавляем следующий код:
if(!is_null($sBigFile)) $sText = '<a href="'.DIR_WEB_ROOT.$sBigFile.'" title="highslide">'.$sText.'</a> ';


Как я к этому пришел? Немного об установке Highslide JS.
Настраивается он следующий образом (как самый простой вариант, без наваротов). В хедер подключается сам скрипт, в нем же указываются некоторые параметры (о них позже) и задаются ссылки следующим образом
<a href="путь к большой картинки" onclick="return hs.expand(this)">
  <img src="путь к маленькой картинки" />
</a>


Значит при генерации кода изображения оставалось добавить только ссылочку с параметром onclick! Не долго думая, я прямо так и сделал! Но, к моему удивлению, когда я сохранил пост событие не работало! Смотря HTML исходник страницы я обнаружил, что моего «онклика» там просто нет.И правильно! Ведь тогда можно было бы впихнуть туда любой JavaScript код и подвергнуть сайт XSS атаке. Первой моей мыслью было добавить свой собственный параметр к ссылке аля
<a href="" highslide> </a> 
И при генерации поста заменить его на нужный onclick. Ввиду своей лени и желания спать мне не хотелось лезть в дебри php кода, разбираться что и как там работает. Поэтому я сделал следующий вариант. При добавлении ссылки можно пользоваться параметром «title». Для ссылки на масштабируемую картинку я указал параметр title=«highslide», а потом с помощь JS обошел все такие ссылки и прописал нужное событие!
Для этого в файл /templates/skin/new/header.tpl где-нибудь под
<script type="text/javascript" src="{$DIR_STATIC_SKIN}/js/panel.js"></script>
нужно добавить следующий код:
<script language="JavaScript" type="text/javascript">
{literal}
 window.addEvent('domready', function(){
      $$('a[title="highslide"]').addEvent('click', function(){return hs.expand(this)});
 });

{/literal}
</script>

Отлично! Теперь настроим собственно сам highslide.
Для начала его нужно скачать (нас интересует «Get the zip package»). Берем от туда packed версию (highslide\highslide.packed.js), чтобы имела меньший размер. Зачем юзеру качать лишние килобайты, правда?
Заливаем его в папку /templates/skin/new/js/.
Далее из скаченного архива содержимое папки highslide\graphics помещаем в /templates/skin/new/images/highslide/. Осталось только подключить и настроить!
Во все тот же header.tpl, над тем куском, что мы вставляли добавим код:
<script type="text/javascript" src="{$DIR_STATIC_SKIN}/js/highslide.packed.js"></script>
<script type="text/javascript">    

    hs.graphicsDir = '{$DIR_STATIC_SKIN}/images/highslide/';
    hs.outlineType = 'rounded-white';
    hs.numberOfImagesToPreload = 0;
    hs.showCredits = false;
{literal}
	hs.lang = {
		loadingText :     'Загрузка...',
		fullExpandTitle : 'Развернуть до полного размера',
		restoreTitle :    'Кликните для закрытия картинки, нажмите и удерживайте для перемещения',
		focusTitle :      'Сфокусировать',
		loadingTitle :    'Нажмите для отмены'
	};
{/literal}
</script>

Что это означает и полный список опций с пояснениями к ним смотрите на официальном сайте highslide.
Вуаля! Мы имеем масштабируемые картинки =) Посмотреть, как оно работает вы можете на проекте фотожаба.ру.

P.S. в предыдущем посте я кратко описывал данный способ. По вашим замечаниям код на jQuery был заменен на Mootools. При написании той статьи о Mootools я только слышал, при написании этой — я с ним уже общался, спасибо за опыт =) Критика приветствуется!
Вряд ли кого-то удивит правило, что деньги должны не лежать, а работать. Прочитав Блог Павла Власова вы узнаете об одном из способов увеличения своих доходов. Простым и понятным языком Павел пишет о Форекс.

56 комментариев

avatar
Большое спасибо!
Ушло в «избранное» и ждет реализации.
avatar
Круто! Огромное спасибо!
avatar
Супер. Спасибо, вечером прикручу. )
avatar
Супер, замечательный эффект.
Вопросик. Насколько разумно использовать 2 js-библиотеки?
Я наверное откажусь от этого эффекта несмотря на всю его прелесть :(
avatar

avatar
это во первых, а во вторых:

<script language="JavaScript" type="text/javascript">
{literal}
 window.addEvent('domready', function(){
      $$('a[title="highslide"]').addEvent('click', function(){return hs.expand(this)});
 });

<b>{/literal}</b>
</script>

avatar
Спасибо, исправил.
avatar
Хотелось бы увидеть альтернативное решение, нежели использование
$$('a[title="highslide"]').addEvent('click', function(){return hs.expand(this)});

потому что если картинка имеет другой комментарий, то скрипт не срабатывает
avatar
вместо title лучше использовать rel
avatar
В таком случае rel=«nofollow» не будет. Предлагаю в /classes/modules/sys_text/Text.class.php строку

$this->oJevix->cfgAllowTagParams('a', array('title', 'href', 'rel'));


заменить на что-нибудь такое

$this->oJevix->cfgAllowTagParams('a', array('title', 'href', 'rel','option'));


Ну и естественно в header.tpl и /include/function.php меняем title на option
avatar
function.php тут не причем, я думаю за это файл скрипта отвечает
avatar
Пардон… имелось ввиду /include/ajax/uploadImg.php. Видимо не то скопировал)
avatar
Пардон, сделал все замены на option, но rel почему-то не отрабатывает

<link href="{$DIR_STATIC_SKIN}/images/globe.png" rel="shortcut icon" />


Не проконсультируете?! ;-)
avatar
тогда class заюзать, вроде как у ссылки нет атрибута option
avatar
Согласен, но тогда мы даем пользователю выбор любого класса, что у нас есть. ИМХО такая свобода это не есть хорошо. Пусть мы жертвуем какой-то части валидности, но стиль ссылки оставим как есть.
avatar
Уважаемый Hrom! Подскажите, пожалуйста, как в итоге-то добиться функциональности, как на фотожабе? Я и так и так «плясал», но добился тока по нажатию на маленькую картинку — открытия большой картинки в том же окне. Как там «класс заюзать» или не заюзать? Пробовал и с option вместо title, но что-то никак((
avatar
можно ещё name, тогда и искать будет быстрее.
avatar
нет, все верно, нужно юзать class, т.к. он в любом случае нужен для тулкита.
avatar
спасибо, получилось! работает!
avatar
На всякий случай сообщаю: автор этой библиотеки в лицензии к ней запрещает её использование в коммерческих проектах.
avatar
Насколько чревато нелегальное использование: забить и использовать или же побояться кары и не использовать?
avatar
Практически это чревато только вашими моральными муками по поводу юридически нечистого кода, сожержащегося в вашем сайте.
avatar
Ясно. А то, может, суд, тюрьма, сухари…
avatar
Всё проверил-перепроверил((( Картинка грузиться в папку big, всё, вроде, в норме. Но если в посте тыкаю на обрезанную картинку, то большая не красиво выплывает, а банально открывается в том же окошке в полном размере… Что бы это могло быть? Чтобы не закосячить rel=«nofollow», выполнил эту рекоммендацию.
В чём может быть несостыковка? Заранее благодарен!
avatar
У вас в header.tpl лишняя строка
<script language="JavaScript" type="text/javascript">

Перед
<script type="text/javascript" src="{$DIR_STATIC_SKIN}/js/highslide.packed.js"></script>


Удалите ее
avatar
И прямь, спасибо, но… Что-то как было усё, так и не работает. При этом у меня сейчас всё настроено, как в оригинальной инструкции, т.е. с title… Вообще не пойму, почему же не фурычит. Скрипт в js, graphic в highslide — не понимаю((
avatar
Верните в header.tpl на option

Т.к. там у вас title, а в теге с картинкой option=«highslide»
avatar
Попробую… Но я спецом в одном посте переименовал обратно в картинке option на title…
avatar
www.avtoturistu.ru/blog/129.html вот… все у вас заработало
avatar
Ничего понимаю… На фотожабе когда тычку в картинку — она красиво так «приезжает» в на передний план в увеличенном виде. А у меня же на сайте банально открывается во весь размер в окне??! Или же кэш почистить?))
avatar
Всё, заработало! Спасибо!!!
avatar
Хм… Что-то иногда (насколько я смог заметить именно скрипт даёт) происходит перегрузка проца сервера Мастерхоста и доступ к сайту временно ограничивается за ошибкой 503… Странно, никто такого не наблюдал?

[Fri Jul 31 10:41:28 2009] [warn] [client 94.25.191.41] CPU limit exceeded (15.0%)
[Fri Jul 31 10:41:28 2009] [warn] [client 94.25.191.41] Resource limit exceeded, access to avtoturistu.ru is temporarily denied
[Fri Jul 31 10:48:08 2009] [warn] [client 213.33.200.126] CPU limit exceeded (15.0%)
[Fri Jul 31 10:48:08 2009] [warn] [client 213.33.200.126] Resource limit exceeded, access to avtoturistu.ru is temporarily denied
[Fri Jul 31 10:48:08 2009] [warn] [client 213.33.200.126] CPU limit exceeded (15.1%)
[Fri Jul 31 10:48:08 2009] [warn] [client 213.33.200.126] Resource limit exceeded, access to avtoturistu.ru is temporarily denied
avatar
И ещё вопрос: почему-то при корректной работе масштабировальщика в ФФ, в эксплорере 7 просто открывается в окне большая картинка (по ссылке). В параметрах эксплорера не нашёл ничего запрещающего исполнения js скриптов… Плохо искал или дело в другом?!
avatar
При этом на фотожабе везде масштабируется, а на моем только в ФФ (пробовала IE, Opera, Chrome — ноль толку, только в окне открывается и всё тут)
avatar
Это потому, что у вас тег
<b></b>
как-то в скрипте оказался)) вот посмотрите сами:

<script language="JavaScript" type="text/javascript"> 
 
 window.addEvent('domready', function(){
      $$('a[option="highslide"]').addEvent('click', function(){return hs.expand(this)});
 });
 
<b></b>
</script>
avatar
Hrom, огроменнейшее Вам спасибо! Дело действительно было в тэге . Появился он у меня вот откуда… Ещё раз спасибо — сейчас радуюсь как ребёнок рабочей функциональности))
avatar
Вы наверное слишком большие изображения грузите
avatar
спасибо! все получилось!
avatar
Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /home/beleberd/domains/beleberda.net/public_html/include/function.php:404) in /home/beleberd/domains/beleberda.net/public_html/classes/modules/sys_session/Session.class.php on line 53

вылазит ошибка + картинки перестают вообще загружатся + когда заходишь на страничку, что бы написать пост, вылазит всплывающие окошко:
Error. Please try again later

avatar
Доработал этот хак.
www.veloxorum.ru/blog/work_in_progress/190.html
avatar
скажите, можете поделиться данным плагином?
насколько я заметил на сайте, в вашем примере титлы для изображений везде одни и теже — «Highslide»?
avatar
забыл сказать:
Большое Спасибо!
avatar
поддерживаю просьбу rominarus
avatar
просим, просим :)
avatar
Очень просим))
avatar
Будет ли работать на версии 0.4 (trunk-r791)?
avatar
сделал все как в инструкции но не работает :( aviators.su/blog/171.html
avatar
Работает как часы.Проверь все ли по мануалу сделал
avatar
спасибо уже все поправил :)
avatar
Сделал все по пунктам и даже несколько раз все перепроверил. Но полное изображение «всплывать» все равно не хочет — открывается в новом окне. При нажатии на картинку появляется надпись «Загрузка» и процесс останавливается. В чем может быть проблема?
avatar
Все сделал — ничего не изменилось…
avatar
подскажите как это все сделать под версию 0.4.1
avatar
Может уже сделал кто для 0.4.2?
avatar
Как насчёт реализации под 0.4.2?
avatar
avatar
Господа с фотожабы! Вашу фотожабу засрали спамеры.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.