Возвращение Даркбокса

Дакрбокс

Самые давние читатели этого блога должны помнить серию заметок, посвящённых скрипту для красивого открытия картинок, написанному в подражание множественным «лайтбоксам»: Даркбокс и Даркбокс 2. С появления этой идеи минуло уже больше двух лет и, вроде бы, уже должны были появиться внятные решения, которые соответствуют всем заявленным в первой заметке условиям. Только вот до сих пор не видно на горизонте ничего приличного. Поэтому Даркбокс возвращается — отбросив версию и все приличия — прямиком на новомодный Github. Столь же красивый и простой — встречайте!

Технологические изменения

Прежде всего, код был полностью переписан в полном соответствии с традициями последнего времени — то есть не мной. Игры в эффективное программирование я, к счастью, бросил. Автором нового кода является Олег Рощупкин, нескучный программист и коллега по песочнице ещё с вебмасконовских времён. Новая версия скрипта некоторое время проходила испытания как на этом сайте, так и на проекте «Веб-стандарты», пока в один чудесный день не появилась на GitHub. Но что-то мешало мне расслабиться и публично заявить о новинке. Всё-таки HTML- и CSS-коду исполнилось почти два года, за которые я успел научиться чему-то новому. Поэтому вся структура и стили были радостно переписаны с нуля.

В основу новой HTML-стуктуры был положен принцип состояний, который был успешно опробован для проекта Open Player, который всё ещё ждёт своего часа и гениального JavaScript-программиста, но об этом в другой раз. Суть принципа сводится к тому, что каждый модификатор, изменяющий состояние всей структуры, применяется к корневому элементу и видоизменяет все нужные элементы через каскад. Это позволяет окончательно очистить JavaScript от оформительских штучек и минимизировать количество операций с атрибутами class. Вот так выглядит код открытой картинки:

	<div class="darkbox darkbox-on darkbox-loaded darkbox-done">
	    <div class="darkbox-shadow"></div>
	    <div class="darkbox-canvas">
	        <img src="picture.jpg" alt="">
	        <div class="darkbox-button darkbox-button-left" title="Close"></div>
	    </div>
	</div>

Как вы можете видеть, вся история открытия картинки записана в атрибуте class корневого элемента. Пройдёмся по ней с самого начала:

  1. По клику пишем на страницу базовый класс darkbox;
  2. Инициализируем его и готовим к загрузке при помощи darkbox-on;
  3. Готовимся к тому, чтобы красиво показать загруженную картинку: darkbox-loaded;
  4. Завершаем все действия, вешаем обработчики закрытия и показываем крестик: darkbox-done.

Как только картинку закрыли, все упомянутые классы успешно очищаются и корневой darkbox, притаившись как тот партизан, продолжает ждать новых вызовов, чтобы повторить описанное упражнение. Исключение из упомянутого принципа состояний только одно — расположение кнопки закрытия окна слева или справа, в зависимости от платформы. Это класс оказался настолько специфическим, что крайне неуместно смотрелся на корневом элементе.

Упомянутые состояния также позволили более наглядно записать CSS-код: теперь он структурирован по принципу базовый класс → модификаторы. Более того, из-за этих чисто архитектурных решений значительно упростился файл хаков для IE, теперь он содержит всего одно правило для IE7, позволяющее окончательно сбросить полупрозрачность, которая задаётся в JavaScript при помощи фильтров:

	* + HTML .darkbox-done .darkbox-canvas {
	    filter:none !important;
	    }

Поддержка IE6 осознанно не предусмотрена, однако магическая сила open source позволит вам не только дописать нужный уровень поддержки, но ещё и предложить её в виде патча к существующему проекту прямо на GitHub. Дерзайте.

Функциональные изменения

Благодаря серьёзному подходу Олега, скрипт теперь умеет обрабатывать битые картинки, для которых не случилось заветного события load. Оформляется это соответствующим запретительным значком. Мои же попытки освежить CSS-код привели к тому, что теперь для анимации загрузочного спиннера используется не анимированный GIF, а восемь последовательно смещающихся состояний спиннера, заключённых в один вертикальный спрайт. Это позволяет получить гораздо более чёткий и аккуратный спиннер, благодаря альфа-прозрачности в PNG-24.

Спрайт
Кадры анимации спиннера, развёрнутые для красоты горизонтально

Другой приятной фичей, появившейся в новой версии, является процесс анимации картинки от загрузчика до её полных размеров. Раньше загрузчик пролетал до полного размера картинки и только потом появлялась она сама. Сейчас картинка появляется в рамках загрузчика и увеличивается вместе с ним либо до полных размеров картинки, либо до размеров окна, если вдруг не удалось вписаться. Плавность анимации картинки разнится от браузера к браузеру, но выглядит вполне сносно, делая происходящее в браузере более интуитивно понятным.

Использование скрипта

Для того, чтобы заставить все эти чудеса работать на ваших страницах, нужно сделать несколько простых вещей. И если описывать все шаги его подключения, то становится ясно, что этот скрипт предназначен не для начинающих сайтостроителей, мол, подключил один JavaSript-файл и погнали — от этого я как раз и пытался уйти, задумывая этот скрипт. Напротив, если вы умеете читать код и понимаете что и как нужно подключить, чтобы всё заработало — то вы поймёте всё из предоставленного примера.

Остаётся только добавить список файлов, необходимых для работы скрипта, примерно в таком порядке — от оформления к динамике:

Весь этот суповой набор можно скачать со страницы проекта на GitHub. Там же, в разделе Issues, вы можете оставить свои замечания, сообщения об ошибках и даже пожелания для будущих версий. Однако это никоим образом не лишает вас возможности порезвиться в комментариях к этому посту.

Комментарии

29

Не хватает одной серьезной штуки, как группового просмотра :)
И есть одна не серьезная, как альты фоток выводить текстом.
Или она в демо не представлена?

deerua, галерейности, скорее всего не будет, т.к. решение хотелось бы держать в достаточно простом виде. А вот про альты вполне можно подумать или даже про title ссылки, чтобы описание можно было прочитать не открывая картинку.

А еще было бы клёво что-нибудь придумать относительно извечной проблемы модального окна с position:fixed;.

Иначе закомплексованным людям с маленьким монитором нельзя будет посмотреть эти большие картинки.

GruZZ, я очень внимательно отнёсся к закомплексованным людям с маленьким монитором. Посмотрите на поведение картинки с рулём на тестовой странице — на самом деле, её размер 1920 × 1200, но она удачно вписывается в окно браузера во время открытия. Так что каким бы ни был ваш монитор, картинка впишется в него полностью.

Хорошая попытка, Вадим. Примерно тоже самое я сделал не так давно. Работает для картинок и контента. Предлагаю объеденить усилия :)

Вот моя попытка: https://github.com/okonet/dialogbox/tree/master/prototype

Есть похожее для мутулза, но хотелось бы framework-agnostic что-то. Но весь цимесь, конечно же, в CSS.

Интересно, но есть недостатки:
— нечувствительность к изменению размеров окна (для телефонов скорее плюс);
— нечувствительность к масштабированию;
— замыленность картинок при масштабировании. Крестик можно border-radius плюс спец.символом или просто SVG.
— подтормаживает анимация под Оперой 11 (это уж не знаю к кому). В IE9 тормозит меньше, в Хроме больше :-).
Не знаю, стоит ли писать в issues.

Кстати, вот грузить для закомплексованных людей картинку 1920px как-то бывает иногда лениво(вспомнилась диалапа). Плюс методы ресайзинга для разных браузеров всегда разный, где-то зернистость, где-то хз что. Как там с ресайзингом в SVG?

GreLI, думаю первые два пункта можно слить в один и закинуть в ишьюз, т.к. вопрос интересный и вполне решаемый. Крестик пробовал сделать хитрее, но кроссбраузерность взяла верх над хитрожопостью :)

boba_KeyOST, с ресайзом в SVG чуть-чуть лучше, т.к. там есть атрибут, отвечающий за то, как ресайзится растр. В принципе, у браузеров тоже есть такие штуки, стоит попробовать. Насчёт больших картинок — это всего лишь демонстрация полезного принципа. Но если вы в своём уме, то не будете выкладывать на сайте большие растры или, по крайней мере, будете предупреждать пользователей об их размерах.

Вадим, сори за офтоп, но "задумать идею" - безграмотно

Привет, Вадим. Твой Darkbox — клёвая штука, и я давно им пользуюсь.

Сейчас меня волнует бюрократический вопрос: на каких правах можно использовать твой скрипт? Ну там, GPL, LGPL, CC0 и прочие WTFPL. А то некоторые кастомеры бывают столь убийственно серьёзны, что лицензию на «Hello world» затребуют.

искал себе галерею. нашел даркбокс :)
переделал на галерею (с прелоадом соседних фоток, чтобы не ждать загрузки), сделал возможность выноса настроек до инициализации. сейчс обкатаю на бетке, потом могу выложить где-нить. по желанию.
удачного проекта

Денис, рад, что скрипт пригодился. В принципе, можно сделать форк на GitHub'е и положить все изменения туда. Может быть некоторые или даже многие решения перекочуют в оригинальный Дакрбокс.

А может пойти еще дальше и вместо спрайта-лоадера использовать одну картину и вращать ее css-анимацией/скриптом (смотря что поддерживается) ;)

Алексей, не очень понятно, как вы предлагаете вращать картинку скриптом. Показывать такой важный для общего UI элемент, как спиннер только в браузерах, которые поддерживают CSS-транформации — значит сильно ограничивать кроссбраузерность скрипта.

Для jquery есть несколько плагинов. Например, jquery-rotate. Хотя, признаться, не тестил их. Чисто спортивный интерес «а что, если» =)

Ну ок — плагины умеют вращать картинки при помощи Canvas, который тоже не поддерживается в IE, раньше 9-й версии. Можно, конечно, прикрутить сюда VML, но гораздо проще двигать спрайт с картинкой ;)

Большое вам спасибо за удачный скрипт! Скажите, пожалуйста, каким образом можно уменьшить прозрачность тени - иной раз просвечивающий пестрый фон мешает рассмотреть саму картинку.

Да, я тоже недавно обнаружил, что не работает. Хотя в превью-версии всё было в порядке. Поправлю.

В последних версиях jquery (старше v1.5.2) почти во всех браузерах скрипт работает некорректно: при попытке открыть одну и ту же картинку более чем несколько раз, окошко начинает появляться и тут же исчезает. Подобное поведение не было замечено в Фаерфоксе. Скрипт был установлен корректно. Как только подключил библиотеку jquery v1.5.2, который прилагался к даркбоксу — проблема сразу исчезла.

Странно, всё заменил и тщательно перепроверил, но результат тот же. Проблема, видимо, с моей стороны. Разберусь, спасибо! :-)

rel="darkbox" - этот атрибут не пропускает валидатор, если doctype для html5
Как сдеалть так что бы код был валидным?

Yvelious, обратите внимание на эту строку кода — вас никто не заставляет использовать rel="darkbox" для обозначения ссылок с картинками. Это может быть любой класс, ID или другая выборка, доступная в jQuery.