Как стать автором
Обновить

Псевдо 3D или параллакс средствами javascript

Время на прочтение3 мин
Количество просмотров17K
Прочитав пост о псевдо 3D эффекте, стало интересно реализовать некий аналог для использования в веб приложениях. За результатом прошу под кат

Основы


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

Разобравшись с теорией приступаем к разработке.

Размещаем слои


Далеко не будем ходить и используем DIV'ы, и CSS свойство z-index нам тоже пригодится.
<div id="background_scene" class="flow" style="background-image:url(res/images/moun.jpg);z-index:2;top:-20px;left:-150px;width:200%;height:200%"></div>
<div id="clouds" class="flow" style="background-image:url(res/images/clouds.png);opacity: 0.5;z-index:3;top:120px;left:400px;"></div>
<div id="dragon" class="flow" style="background-image:url(res/images/dragon.png);z-index:5;top:120px;left:500px;"></div>

Выше я привел 3 спрайта с классом .flow, начальными координатами и картинками. Теперь пора заставить их двигаться.

Вращение девайса


Все наши потребности в получении положения в пространстве удовлетворит событие: window.ondevicemotion.
window.ondevicemotion = function(event) {  
     X = event.accelerationIncludingGravity.x;  
     Y = event.accelerationIncludingGravity.y;  
     Z = event.accelerationIncludingGravity.z;
}

Не буду расписывать событие, любопытных отправляю в список литературы.
Нам же из этого события необходимо 2 значения: Х и У.
Высчитываем дельту смещения:
    deltaX = lastX - X;
    deltaY = lastY - Y;
    lastY = Y;
    lastX = X;

Находим все спрайты по имени класса .flow
Т.к. спрайты с малым z-index'ом 'самые «удаленные» и должны двигаться в обратном направлении, движения для каждой группы высчитываем отдельно:
elements = $('div.flow');
 elements.each(function (key, layer) {
        zIndex = layer.style.zIndex;
        sprite = $('#' + layer.id);
                if (zIndex > 9) { //Я решил что дальние спрайты это спрайты с z-index < 10
                    anim = {"left":"-=" + deltaX * zIndex * 2, "top":"+=" + deltaY * zIndex * 0.5}; //0.5  это случайный коэффициент пришедший в голову, использую эти коэффициенты для отладки скоростей движения слоев
                } else {
                    anim = {"left":"+=" + deltaX * zIndex * 2, "top":"-=" + deltaY * zIndex * 2};
                }
sprite.animate(anim, 100); //Используем анимацию из jQuery
}

Помимо своей обычной задачи z-index выполняет еще роль коэффициента для ускорения движения спрайтов.
Ну вот в принципе и все.

Улучшения


1. Для уменьшения числа срабатывания метода движения слоев, была добавлена активация по таймеру. Это дало прироста, но увеличение интервала влечет за собой дерганность анимации.
2. Для уменьшения тряски дельта высчитывается иначе: дельта = Х — Хсредн; Хсредн — высчитывается в моментах интервала таймера. Даже если в последний момент вы тряхнете рукой, все будет гладко.
3. Добавлена поддержка ориентаций экрана

Проблемы


1. Тряска все еще заметна, не знаю, надо калибровать или совершенно другой алгоритм писать надо
2. Не могу толком настроить скорости спрайтов

Можно было бы сделать


1. Простенький дизайнер Drag&Drop спрайтов, с регулированием уровня
2. Работа не только с акселерометром, но и с мышкой, скролл баром (в зависимости от доступности или настроек)
3. Работа с камерой возможна, но…

Рекомендую ознакомиться

демка (если на устройстве не поддерживается devicemotion, то включится рандомный генератор наклонов)

В качестве кода и примера виновно малое время от идеи до реализации. Будет любопытно узнать мнение, подсказки. Если будет интерес, то постараюсь доделать библиотеку.

UPD: Не было и нет возможности протестировать на Andriod девайсах. И, к сожалению, код на них не работает. Попробую поискать решение.
Теги:
Хабы:
Всего голосов 16: ↑10 и ↓6+4
Комментарии10

Публикации

Истории

Работа

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
20 – 22 сентября
BCI Hack Moscow
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
24 сентября
Astra DevConf 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн