Верша свой круг, назначенный от века,
Роняет Небо наземь хлопья снега...
Мария Семенова
После жаркого-жаркого лета (или не жаркого, как в этом году в Москве) и дождливой осени снежная зима приносит с собой предпраздничное настроение — близится Новый год, когда родные и близкие собираются за одним столом теплой компанией и радуют друг друга застольными беседами. Вот и мы порадуем на этот раз снежным настроением наши сайты.
Начинаем с создания объекта — снежинки. Общий принцип выберем такой — объект конструирует полностью готовую снежинку, а пользователь может уже созданный экземпляр полностью настраивать под себя.
Определим основные параметры:
speed — количество миллисекунд между двумя движениями снежинки; deltaX — максимальное отклонение по оси X снежинки от предыдущего в пикселях; deltaY — расстояние смещения снежинки между двумя движениями в пикселях; imgSrc — путь к картинке, изображающей снежинку.Сами по себе снежинки летать не будут — их надо поместить в контейнер. В качестве контейнера для снежинки будем использовать объект DIV. В дальнейшем, задавая параметры этого контейнера, можно настраивать внешний вид снежинки.
Вы помните, что в разных браузерах (а если не повезло, то и в разных версиях одного и того же браузера) один и тот же код может работать по-разному? В частности, по-разному задаются координаты контейнера. Для определения способа нам хватит названия браузера. Чтобы его выяснить, обратимся к свойству navigator.appName — в нем содержится точное название браузера, в котором открыта страница, чем мы и воспользуемся. Будем считать, что если в строке присутствует название Internet Explorer, то так оно и есть, а во всех остальных случаях мы будем рассчитывать на FireFox. В Opera, к счастью, все тоже работает.
Выбрав браузер, мы определяем функцию позиционирования снежинки setPositionXY();
Полный текст вы можете увидеть во фрагменте кода «Проверка браузера».
Проверка браузера |
this.browser.scrollTop = function () { return (document.body.scrollTop); } this.browser.scrollLeft = function () { return (document.body.scrollLeft); } this.browser.min_x=1; this.browser.min_y=1; if(navigator.appName.indexOf("Internet Explorer")!=-1) { this.browser.max_x=document.body.clientWidth; this.browser.max_y=document.body.clientHeight; // позиционирование для IE this.setPositionXY = function (x,y) { var x=x||this.x; var y=y||this.y; this.div.style.pixelLeft=x; this.div.style.pixelTop=y; } } else { this.browser.max_x=self.innerWidth; this.browser.max_y=self.innerHeight; // позиционирование для FireFox this.setPositionXY = function (x,y) { var x=x||this.x; var y=y||this.y; this.div.style.left=x+'px'; this.div.style.top=y+'px'; } } |
В отдельный метод calc() выделим все вычисления новых координат снежинки. В принципе, формулу для траектории снежинки можно взять любую — мы за основу выбрали синусоидальную (фрагмент кода «Новые координаты»).
Новые координаты |
// вычисляем новое положение this.calc = function (x,y,dx,dy) { var dx=dx||this.deltaX; var dy=dy||this.deltaY; // вычисление новой координаты x=x+dx*Math.sin(this.browser.max_y-this.browser.min_y-this.start_y); y=y+dy; // проверка по диапазону if (x>this.browser.max_x) x=this.browser.min_x; if (x if (y if (y>this.browser.max_y) y=this.browser.min_y; return({'x':x,'y':y}); } |
Зная координаты, мы можем переместить контейнер со снежинкой на новое место — с помощью метода move().
Перемещение |
// перемещаем снежинку this.move = function () { var new_pos=[]; // уточним текущее положение снежинки и очистим его от скроллинга var x=Math.floor(this.x — this.browser.scrollLeft()); var y=Math.floor(this.y — this.browser.scrollTop()); // вычислим новое положение снежинки new_pos=this.calc(x,y); // вернём смещение this.x=new_pos['x']+this.browser.scrollLeft(); this.y=new_pos['y']+this.browser.scrollTop(); this.setPositionXY(this.x,this.y); if (!this.div.width) {this.div.width=this.div.offsetWidth;this.browser.max_x-=this.div.width;this.browser.min_x+=this.div.width;} if (!this.div.height) {this.div.height=this.div.offsetHeight;this.browser.max_y-=this.div.height;this.browser.min_y+=this.div.height;} } |
Это факт: на самом деле наш снегопад — частный случай партикловых систем, применяющихся в играх для создания дымов, взрывов и подобных эффектов. О партиклах в нашем журнале уже писал Ричард Псмит в №10 за 2005 год.
Но нам нужно будет переместить снежинку не один раз. JavaScript позволяет вызывать определенное действие (функцию) по истечении заданного промежутка времени — с помощью стандартного метода setTimeout объекта window.
Мы создадим еще один метод, который перемещает снежинку и затем вызывает сам себя через время, заданное в параметре this.speed. Время у нас измеряется в миллисекундах.
Шаг снежинки |
this.step = function () { this.move(); window.setTimeout(this.handler+".step()",this.speed); } |
Итак, устанавливаем снежинку на старт и добавляем подготовленный контейнер к документу. Затем плодим и размножаем снежинки, то есть получаем экземпляры объекта snowflake и кладем их в один большой массив.
Снежинки у нас будут разные:
большие — случайным образом выбранные картинки: и помельче, и наконец, просто символ *.Скорость передвижения и интервал между перемещениями будем выбирать случайно.
Этот фрагмент кода — в листинге «Снегопад начинается».
Снегопад начинается |
var snowflakes = []; for (var i=0; i< 5; i++) { snowflakes=new snowflake(); snowflakes.imgSrc=(['snow1.gif','snow.gif'])[Math.floor(Math.random()*2)]; snowflakes.speed=([60,90,120])[Math.floor(Math.random()*3)]; snowflakes.draw(); snowflakes.start(); } for (var i=5; i< 15; i++) { snowflakes=new snowflake(); snowflakes.imgSrc='snow2.gif'; snowflakes.speed=([20,40])[Math.floor(Math.random()*2)]; snowflakes.draw(); snowflakes.start(); } for (var i=15; i< 30; i++) { snowflakes=new snowflake(); snowflakes.speed=([20,50,90])[Math.floor(Math.random()*3)]; snowflakes.draw = function () { this.div.innerHTML="*"; this.div.style.color=(["#9DFFCD","#FFB99D","#F7FF9D"])[Math.ceil(Math.random()*3-1)];; this.div.style.fontSize=([30,50,90])[Math.ceil(Math.random()*3-1)]; } snowflakes.draw(); snowflakes.start(); |
Вот, собственно говоря, и все. Построенный объект snowflake легко настраивается именно благодаря своим открытым методам и отделением оформления от вычислений. Так что каждый читатель при желании сможет переделать этот снегопад к 14 февраля — дню Святого Валентина — в сердечки, летящие вверх.
Полностью код страницы и картинки к этой статье вы найдете на нашем диске. А пока — с Новым годом!