От автора: в предыдущей статье я познакомил вас с WebGL. Также я объяснил, почему для создания нативного 3D контента на страницах буду использовать фреймворк threeJS для демонстрации возможностей WebGL. В этой статье я покажу вам, как сделать 3D камеру и кнопки для взаимодействия между WebGL контентом и HTML страницей.
Я все объясняю тщательно и пошагово по мере нашего продвижения, в этой статье вы не научитесь рендерить сцены. Об этом я расскажу в сопроводительных статьях по созданию сцен. Хотите увидеть конечный результат – можете посмотреть демо на CodePen.
Музыка сфер
WebGL может быть единственным контентом на странице, однако у данной технологии есть одно преимущество. WebGL является веб-технологией, основанной на стандартах, что значит, что ее можно бесшовно интегрировать с HTML контентом. У canvas не хватает доступности и SEO, поэтому было бы умно создавать WebGL сцену прогрессивно: текст будет представлен в виде HTML-текста с добавлением WebGL контента там, где это возможно. Для нашей страницы о Марсе нам понадобится следующая разметка:
1 2 3 4 5 6 7 |
<div id="marsloc"></div> <article id="marsinfo"> <h1>Mars</h1> <div> <p>Home to both the Solar System’s highest mountain… </div> </article> |
Элемент marsloc будет хранить наш WebGL контент для рендеринга, поверх которого будет лежать HTML контент. Делается это с помощью CSS на Sass:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
body { background: black; margin: 0; min-height: 100vh; color: #fff; } #marsloc { cursor: grab; } #marsinfo { position: absolute; top: 0; width: 100%; padding: 2rem; } #marsinfo h1 { font-size: 8vw; margin-top: 0; font-weight: 100; line-height: 1; position: absolute; } #marsinfo div { width: 40%; position: absolute; background-color: rgba(0,0,0,0.3); right: 0; padding: 1.3rem; line-height: 1.6; font-size: 1.2rem; pointer-events: none; @media all and (max-width: 540px) { width: 100%; left: 0; top: 40vw; } } |
Курсор в виде руки на элементе #marsloc – это UI подсказка для WebGL контента. Блоку div внутри #marsinfo задано свойство pointer-events: none, чтобы его контент не мешал при взаимодействии с планетой.
Создание планеты
HTML и CSS есть, осталось подключить последнюю версию threeJS с CDN в нижней части страницы:
1 2 |
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.js"> </script> |
Библиотека threeJS должна быть подключена раньше, чем мы начнем использовать ее код.
Наш следующий файл-скрипт начинается с установки ряда переменных и констант, которые будут использоваться в нашем коде:
1 2 3 |
var container, controls, camera, renderer, scene, light, marsMesh, clock = new THREE.Clock(); const imgLoc = "//s3-us-west-2.amazonaws.com/s.cdpn.io/4273/"; |
Переменная clock поможет нам анимировать движения Марса по умолчанию. imgLoc – положение всех изображений. Переменная объявлена здесь, чтобы потом не повторяться.
Область обзора
Первый элемент, который мы создадим, будет камера. Камера нужна, чтобы «видеть» созданную нами сцену. В threeJS есть несколько типов камер:
perspectiveCamera: параллельные линии в сцене будут сходиться, если они достаточно длинные (представьте, что вы стоите посреди железнодорожных путей и смотрите вдаль). Дальние объекты будут иметь меньший размер. Задействован принцип нашего зрения, то, как мы видим мир.
OrthographicCamera: параллельные линии в сцене не пересекаются вне зависимости от их длинны. Объекты не становятся меньше по мере удаления. Такая камера хорошо подходит для рендеринга UI элементов и некоторых архитектурных видов.
Для камеры с перспективой нам также понадобится задать «область обзора» (часто сокращается как FOV). FOV – угол обзора камеры. Узкая область обзора фокусирует камеру на отдельной части сцены (представьте лошадь, на которую надели защитные очки, сужающие область обзора, чтобы та не пугалась и не отвлекалась). Визуальные элементы, не входящие в эту область, отсекаются. Широкая область обзора видит больше, но объекты становятся меньше и отодвигаются дальше.
Также нам понадобится задать соотношение сторон камеры: коэффициент отношения ширины к высоте отрендеренного вида. Вы, скорее всего, знаете про соотношение сторон из кино. Широкоформатные фильмы, как правило, более «кинематографичные» и захватывающие. Низкое соотношение сторон (ближе к квадрату) придает фильму интимности и старит фильм.
Почти во всех случаях соотношение сторон должно отражать окно пользователя: то есть ширина окна браузера, разделенная на его высоту.
Последние два значения камеры – ближняя и дальняя плоскости отсечения — near и far. По умолчанию 3D камера «смотрит» бесконечно вдаль: в отличие от реального мира, здесь объектив 3D камеры не закрывается частицами, взвешенными в атмосфере, а также не ограничивается возможностями линз. В играх этот эффект часто называют «дальностью прорисовки». Одна из причин, почему в ранних 3D играх было много тумана и узких коридоров – чем меньше элементов нужно отрисовывать, тем быстрее игра.
Нам нужно, чтобы ближняя плоскость отсечения камеры была почти вплотную к воображаемой линзе, а дальняя – на разумном расстоянии. Между двумя плоскостями отсечения будут находиться наши элементы сцены. Код:
1 2 |
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000); |
Сейчас наша камера парит в бесконечном черном пространстве и ни на что не смотрит. В следующей статье я расскажу про суть 3D пространства, как его осветить, а также как добавить объекты на сцену.
Источник: //thenewcode.com/
Редакция: Команда webformyself.