Если Вы занимаетесь веб-программированием, трудно быть специалистом только в одной области.
Я занимаюсь разработкой скриптов на php, но фактически это означает, что требуется
ещё знать и JS, HTML, CSS, если не в совершенстве, то хоть как-нибудь.
Амбула
Пришёл заказчик с желанием разместить у себя на главной странице плеер картинок.
Были прдъявлены следующие требования:
плавная смена картинок
картинки должны показываться только когда загрузятся
До этого у заказчика уже была сделана галерея на ява-скрипте. Проблема была в том,
что в режиме автоматической смены картинок, изображения не успевали загружаться и отображаться,
толку от такой галереи было мало.
Использовать уже готовый скрипт желания не было, поэтому пришла идея
написать простой скрипт на все случаи жизни.
Немного про фильтры
Фильтры устанавливаются через CSS в виде списка. Выглядит это следующим образом:
Старый стиль поддерживается IE, начиная с версии 4, новый только с 5.5.
Новый стиль предоставляет больше фильтров и большее число параметров, которое можно
передавать фильтру. Но, если честно, я не нашёл существенных различий, большенство фильтров
нового стиля так или иначе доступны и в старом. Единственное - новый стиль позволяет делать
более тонкие настройки.
Фильтры, которые накладываются на изображение, можно просто прописать через CSS,
но применятся они, только если разрешено выполнение скриптов. Прописать их можно так:
Фильтры, которые делают анимированный переход, нужно сначало прописать в стилях, перед
изменением изображения применить, потом изменить картинку, а после этого запустить
воспроизведение. Например, так:
Помимо плавного перехода blendTrans для трансформации можно использовать анимированный фильтр revealTrans, у которого
есть дополнительный параметр transition, отвечающий за вид трансформации.
Параметр transition должен содержать целое положительное число.
Нужно разработать ява-скрипт для простой смены картинок с возможностью использовать
фильтры. Список картинок заранее известен. Скрипт должен корректно работать в браузерах
IE, FF, Opera. Если JavaScript отключён, то должен отрабатывать простой HTML. Картинки
должны отображаться циклично.
Разработка
Первоначально есть только список слайдов, на основе которого нужно сделать слайд-шоу.
Список всегда можно представить как одномерный массив, поэтому в качестве прототипа я
выбрал объект Array. Сильной стороной JavaScript является простота расширения объектов,
поэтому можно создать объект любого типа и расширить его функционал до необходимого.
Таким образом, ImageList изначально является объектом "массив", дополнительно
расширен функцией, которая может добавлять в него картинки. Для добавления слайда в
список воспроизведения достаточно вызвать ImageList.addImage('путь до картинки').
В массиве ImageList будет находиться четыре объекта Image. К слову, подгрузка изображений
начинётся сразу после добавления нового изображения к списку, поэтому не стоит изначально
делать большой список, новые изображения можно добавлять в любой момент времени.
Далее я определил необходимые свойства нового объекта.
Никаких хитростей в этой функции нет - если флаг воспроизведения не установлен, то
устанавливаем его и показываем следующее изображение. Все хитрости будут описаны в
функции next().
Если флаг воспроизвдения установлен, то убираем таймер и сбрасываем флаг воспроизведения.
Таймеры я использую просто потому, что не нашёл никакого другого способа организовать
паузы, которые бы не грузили систему.
Переход к следующему слайду
ImageList.next = function() {
if ( this.playing && this.length && this.img )
{
// Check endif ( this.cur >= this.length ) this.cur = 0;
// Check complete statusif ( !this[this.cur].complete )
{
setTimeout("ImageList.next()", 50); // wait, while image is loadingreturnfalse;
}
if ( this.imgFilter )
{
// Set random transitionif ( typeof(this.imgFilter.transition) != 'undefined' )
this.imgFilter.transition = Math.floor(Math.random() * 99);
this.imgFilter.apply();
}
// Change imagethis.img.src = this[ this.cur++ ].src;
// Set next timerthis.timer = setTimeout("ImageList.next()", this.delay);
// Play filterif ( this.imgFilter ) this.imgFilter.play();
returntrue;
}
}
Логика работы этой функции следующая - если флаг воспроизведения установлен, в
списке есть изображения и объект, который будет отображать слайды установлен, то
выполняем работу по смене изображения. Проверяем, может быть, пора повторить
список сначала? Дальше проверяем, загрузилось ли изображение, если нет, то повторим
попытку через 50 мс, затем применяем фильтр, если таковой установлен. Потом меняем
слайд, увеличивая текущий индекс, после этого устанавливаем таймер для
показа следующего изображения. И, наконец, если фильтр был задан, то проигрываем его.
Установка объекта <img>
ImageList.setImg = function(Img) {
this.img = Img;
this.imgFilter = null;
try
{
// Try to get filter (IE only)for (var i in Img.filters)
{
if ( typeof(Img.filters[i]) != 'object' ) continue;
if ( typeof(Img.filters[i].apply) == 'undefined' ) continue;
if ( typeof(Img.filters[i].play ) == 'undefined' ) continue;
this.imgFilter = Img.filters[i];
break;
}
}
catch(e)
{
// No filter :'(
}
}
Изначально эта функция не планировалась, но встал вопорос, каким образом извлекать
установленный на объекте <img> фильтр, и я решил сделать специальную функцию.
Поскольку фильтры доступны пока только в IE, то нужно поместить код для
выбора фильтра в конструкцию try ... catch, чтобы избежать проблем с теми
браузерами, которые не поддерживают фильтры.
Если у Вас включён JavaScript, то изображение, которое расположено ниже, будет меняться.
Если используется Internet Explorer 4+, то слайды должны плавно сменять друг друга.