Для сайта компании «Международный Центр Финансовых Операций » заказчик попросил сделать часы со стрелками, показывающие время в Москве, Нью-Йорке и Токио. Первое, что могло бы прийти в голову – «Flash». А не тут-то было… Часики очень быстро можно сделать и на HTML+CSS+JavaScript.
Самое сложное и долгое это, пожалуй, спрайты стрелок.
Дизайнер приготовил для меня контуры стрелок в Photoshop, а я с помощь экшина создал 24 слоя, на которых стрелки повернуты на 15° относительно предыдущего слоя. Признаюсь, что эти значения были выбраны эмпирически исключительно исходя из здравого смысла. Часы на странице носят скорее декоративный характер, нежели практически и поэтому сомнительно, что кто-то будет за ними специально следить. Технически, можно было бы сделать и все 60 фаз.
Затем я расположил слои один над другим, чтобы изменять изображение исключительно с помощью смещения положения фона у блока.
В стрелки часов я отделил от фона с помощью техники, аналогичной той, что описывал Сергей Чикуенок в статье «Как вырезать картинку из фона ». Использовать PNG-24 с прозрачностью было не приемлемо из-за отсутствия поддержки в IE6, а отрисовка таких мелких деталей без антиалиасинга выглядела просто ужасно.
Итак, подготовительные работы закончены. Приступаем к созданию механизма часов.
<div id="clocks">
<div class="city moscow">
<div class="hour"></div>
<div class="minute"></div>
</div>
<div class="city newyork">
<div class="hour"></div>
<div class="minute"></div>
</div>
<div class="city tokyo">
<div class="hour"></div>
<div class="minute"></div>
</div>
</div>
#clocks {
background: url(clocks-template.png) no-repeat left top;
width: 150px;
height: 77px;
position: relative;
}
#clocks .city,
#clocks .hour,
#clocks .minute {
width: 45px;
height: 45px;
position: absolute;
}
#clocks .city {
overflow: hidden;
top: 14px;
}
#clocks .hour {
background: url(clock-hour-sprite.gif) no-repeat 0 0;
}
#clocks .minute {
background: url(clock-minute-sprite.gif) no-repeat 0 0;
}
#clocks .moscow {
left: 0;
}
#clocks .newyork {
left: 53px;
}
#clocks .tokyo {
left: 105px;
}
(function () {
var dateObj = new Date();
var m = dateObj.getMinutes(), h = dateObj.getHours() + (dateObj.getTimezoneOffset() + m) / 60;
Переменные m и h содержат минуты и часы соответственно. Более того, значение часов приведено к GMT и скорректировано в зависимости от количества минут.
Вычисляем номер спрайта для минут и часов. Причем, нужно предусмотреть возможность изменение часового пояса при вычислении.
var minute = Math.floor((m + 1.25) / 2.5) % 24;
function getHourForCity(h, offset) {
return Math.floor((12 + h + offset + 0.25) / 0.5) % 24;
}
Волшебная функция, которая позволит нам определить используется ли у пользователя «летнее» время в системе или нет.
function daylightSaving() {
var now = new Date(),
nowTZ = now.getTimezoneOffset(),
winterTZ = new Date(now.getFullYear(), 1, 1).getTimezoneOffset(),
summerTZ = new Date(now.getFullYear(), 7, 1).getTimezoneOffset();
return (winterTZ !== summerTZ) && (nowTZ === summerTZ) ? 1 : 0;
}
var recovery = daylightSaving();
Устанавливаем позицию фона так, чтобы отобразилась нужная нам стрелка.
$('#clocks .minute').css('backgroundPosition', 'left -' + 45 * minute + 'px');
$('#clocks .mosсow .hour').css('backgroundPosition', 'left -' + 45 * getHourForCity(h, 3 + recovery) + 'px');
$('#clocks .newyork .hour').css('backgroundPosition', 'left -' + 45 * getHourForCity(h, -5 + recovery) + 'px');
В Японии не переводят стрелки на «летнее» время, по этому коррекция часового пояса не требуется.
$('#clocks .tokyo .hour').css('backgroundPosition', 'left -' + 45 * getHourForCity(h, 9) + 'px');
Обновляем положение стрелок каждую минуту. Мне очень нравится этот шаблон – замыкание + setTimeout, потому что он позволяет выполнить функцию сразу, чего не может обеспечить setInterval.
setTimeout(arguments.callee, 60000);
})();