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

87
По просьбе товарища 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 я только слышал, при написании этой — я с ним уже общался, спасибо за опыт =) Критика приветствуется!
  • +14
  • 21 мая 2009, 02:50
  • Hrom

Комментарии (55)

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

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

<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>

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

потому что если картинка имеет другой комментарий, то скрипт не срабатывает
0
вместо title лучше использовать rel
+1
  • avatar
  • ort
  • 21 мая 2009, 12:47
В таком случае 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
0
function.php тут не причем, я думаю за это файл скрипта отвечает
0
Пардон… имелось ввиду /include/ajax/uploadImg.php. Видимо не то скопировал)
0
Пардон, сделал все замены на option, но rel почему-то не отрабатывает

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


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

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


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

Т.к. там у вас title, а в теге с картинкой option=«highslide»
+1
Попробую… Но я спецом в одном посте переименовал обратно в картинке option на title…
0
www.avtoturistu.ru/blog/129.html вот… все у вас заработало
0
Ничего понимаю… На фотожабе когда тычку в картинку — она красиво так «приезжает» в на передний план в увеличенном виде. А у меня же на сайте банально открывается во весь размер в окне??! Или же кэш почистить?))
-1
Всё, заработало! Спасибо!!!
+1
Хм… Что-то иногда (насколько я смог заметить именно скрипт даёт) происходит перегрузка проца сервера Мастерхоста и доступ к сайту временно ограничивается за ошибкой 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
0
И ещё вопрос: почему-то при корректной работе масштабировальщика в ФФ, в эксплорере 7 просто открывается в окне большая картинка (по ссылке). В параметрах эксплорера не нашёл ничего запрещающего исполнения js скриптов… Плохо искал или дело в другом?!
0
При этом на фотожабе везде масштабируется, а на моем только в ФФ (пробовала IE, Opera, Chrome — ноль толку, только в окне открывается и всё тут)
0
Это потому, что у вас тег
<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>
+1
Hrom, огроменнейшее Вам спасибо! Дело действительно было в тэге . Появился он у меня вот откуда… Ещё раз спасибо — сейчас радуюсь как ребёнок рабочей функциональности))
0
Вы наверное слишком большие изображения грузите
+1
спасибо! все получилось!
0
  • avatar
  • gevak
  • 07 августа 2009, 16:11
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

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