Вебмастерам: 3D-веб тремя способами
2014-08-01
В этой статье мы рассмотрим несколько способов размещения 3D контента, созданного с помощью Blend4Web, на веб-сайтах.
Способ 1: вставка HTML-файла
Одной из интересных особенностей Blend4Web является возможность экспортировать целые сцены из Blender'а в единственный HTML-файл, не имеющий внешних зависимостей. Такой файл представляет собой самодостаточную веб-страницу, открывающуюся стандартным браузером, которую можно распространять различными способами. В частности, ее можно разместить на веб-сайте внутри контейнера iframe, указав для него размеры и другие поддерживаемые свойства.
<!DOCTYPE html>
<html>
<head>
<title>Apple</title>
</head>
<body>
<iframe width="800" height="500" allowfullscreen src="/tutorials/examples/web_page_integration/apple.html"></iframe>
</body>
</html>
Основное преимущество этого способа заключается в его простоте. Пользователи, не имеющие опыта работы с Blend4Web, могут придерживаться следующего порядка действий:
- загрузить и установить аддон для программы Blender (см. видео или раздел руководства пользователя);
- экспортировать предварительно созданную сцену File > Export > Blend4Web (.html);
- разместить полученный HTML-файл на сайте внутри контейнера iframe.
Способ 2: веб-плеер
Второй способ является вариантом первого - в результате на странице появляется вставка 3D контента с элементами управления.
Тем не менее, реализация вставки этим способом существенно отличается от предыдущего - вместо единственного HTML-файла здесь используется комбинация веб-плеера и загружаемого JSON-файла сцены.
<!DOCTYPE html>
<html>
<head>
<title>Apple</title>
</head>
<body>
<iframe width="800" height="500" allowfullscreen src="/apps/webplayer/webplayer.html?load=/tutorials/examples/web_page_integration/apple.json&show_fps"></iframe>
</body>
</html>
Директорию с файлами веб-плеера blend4web/deploy/apps/webplayer/ можно скопировать из дистрибутива Blend4Web SDK и разместить на сайте.
JSON-файлы сцены можно экспортировать аналогично HTML-файлам с помощью опции File > Export > Blend4Web (.json). Полученные файлы можно разместить на сайте и указать путь к ним (абсолютный или относительный) с помощью параметра веб-плеера load.
В этом примере помимо обязательного параметра load мы использовали необязательный - show_fps - для отображения счетчика кадров в секунду.
Подробнее с веб-плеером можно ознакомиться в соответствующем разделе руководства пользователя.
Примечание
Чтобы запускать веб-плеер из локальной файловой системы (т.е. без веб-сервера) необходимо настроить браузер для загрузки локальных ресурсов.
Хотя этот способ выглядит более сложным, чем предыдущий, он имеет ряд преимуществ:
- компактный формат файлов сцены - загрузка происходит быстрее;
- сцена загружается асинхронно, без блокировки загрузки всей страницы;
- данные сцены хранятся отдельно от самого веб-плеера, что позволяет использовать их в других приложениях.
Способ 3: веб-приложение
Наконец, мы можем превратить саму веб-страницу в интерактивное 3D приложение! Продемонстрируем это на простом примере: разместим на странице кнопку, при нажатии на которую будет вопроизводиться интересный анимационный эффект.
В состав бесплатного дистрибутива также входит отдельное приложение, упрощающее изучение и отладку.
Обратите внимание: содержимое страницы просматривается не только сквозь невидимый элемент canvas, но и за полупрозрачными трехмерными объектами, которые, в свою очередь, корректно отображают блики во время движения.
О том, как был создан сам анимационный эффект, будет рассказано в следующей статье, а сейчас посмотрим, как подключить его к странице. Как мы увидим, сделать это не сложнее, чем реализовать какой-нибудь эффект на jQuery или Flash.
Для начала подключим к странице скрипт движка b4w.min.js из дистрибутива Blend4Web. Код примера разместим в файле example.js. Таблицу стилей приложения будем хранить в файле example.css:
<link rel="stylesheet" type="text/css" href="example.css">
<script type="text/javascript" src="b4w.min.js"></script>
<script type="text/javascript" src="example.js"></script>
Разместим на странице контейнер для области отрисовки и кнопку для запуска эффекта. Для удобства обернем их элементом div#wrapper_container:
<div id="wrapper_container">
<div id="canvas_cont"></div>
<div id="run_button" class="ru"></div>
</div>
Рассмотрим таблицу стилей приложения:
#canvas_cont {
position: absolute;
width: 1200px;
height: 1200px;
bottom: -350px;
pointer-events: none;
}
div#wrapper_container {
position: relative;
}
@media screen and (min-width: 1000px) and (max-width: 1200px) {
#canvas_cont {
height: 1000px;
width: 1000px;
}
}
@media screen and (max-width: 1000px) {
#canvas_cont {
width: 100vw;
height: 100vw;
bottom: 0;
}
}
div#run_button.ru,
div#run_button.en {
width: 236px;
height: 60px;
margin: 0 auto;
cursor: pointer;
background-image: url(interface/button.png);
background-size: 472px 120px;
}
div#run_button.en {
background-position: -236px 0;
}
div#run_button.ru:hover {
background-position: 0 -60px;
}
div#run_button.en:hover {
background-position: -236px -60px;
}
Для контейнера области отрисовки зададим ширину, высоту и абсолютное позиционирование. Также сместим контейнер вниз, относительно родительского элемента на 350px. Выставим свойство pointer-events равным none. Данное свойство делает элемент прозрачным для событий мыши:
#canvas_cont {
position: absolute;
width: 1200px;
height: 1200px;
bottom: -350px;
pointer-events: none;
}
Примечание
Более подробно ознакомиться со свойством pointer-events можно по адресу developer.mozilla.org/en-US/docs/Web/CSS/pointer-events.
Зададим относительное позиционирование для элемента div#wrapper_container. Это необходимо для того, чтобы дочерние элементы, имеюшие абсолютную позицию, оставались внутри родительского контейнера:
div#wrapper_container {
position: relative;
}
Cкорректируем высоту, ширину и расположение области отрисовки для устройств с небольшими экранами:
@media screen and (min-width: 1000px) and (max-width: 1200px) {
#canvas_cont {
height: 1000px;
width: 1000px;
}
}
@media screen and (max-width: 1000px) {
#canvas_cont {
width: 100vw;
height: 100vw;
bottom: 0;
}
}
Установим стили для кнопки запуска:
div#run_button.ru,
div#run_button.en {
width: 236px;
height: 60px;
margin: 0 auto;
cursor: pointer;
background-image: url(interface/button.png);
background-size: 472px 120px;
}
div#run_button.en {
background-position: -236px 0;
}
div#run_button.ru:hover {
background-position: 0 -60px;
}
div#run_button.en:hover {
background-position: -236px -60px;
}
Теперь разберем скрипт example.js. Ниже целиком приведен его код:
"use strict";
b4w.register("example_main", function(exports, require) {
var m_anim = require("animation");
var m_app = require("app");
var m_data = require("data");
var m_main = require("main");
var m_scs = require("scenes");
var m_sfx = require("sfx");
exports.init = function() {
m_app.init({
canvas_container_id: "canvas_cont",
callback: init_cb,
physics_enabled: false,
alpha: true,
report_init_failure: false,
media_auto_activation: false
});
}
function init_cb(canvas_elem, success) {
if (!success) {
console.log("b4w init failure");
return;
}
if (window.web_page_integration_dry_run)
m_data.load("flying_letters.json", load_cb);
else
m_data.load("/tutorials/examples/web_page_integration/flying_letters.json", load_cb);
resize();
window.addEventListener("resize", resize);
}
function resize() {
m_app.resize_to_container();
}
function load_cb(root) {
var letters_arm = m_scs.get_object_by_name('beads_armature');
m_anim.stop(letters_arm);
run_button.addEventListener("mousedown", demo_link_click, false);
}
function demo_link_click(e) {
m_data.activate_media();
var letters_arm = m_scs.get_object_by_name('beads_armature');
var spk = m_scs.get_object_by_name("Speaker");
m_sfx.play_def(spk);
m_anim.apply(letters_arm, "flying_letters");
m_anim.play(letters_arm, letters_obj_cb);
}
function letters_obj_cb(obj) {
m_anim.apply(obj, "flying_letters_idle");
m_anim.set_behavior(obj, m_anim.AB_CYCLIC);
m_anim.play(obj);
}
});
b4w.require("example_main").init();
Обратите внимание на параметры инициализации - прозрачность области отрисовки alpha включена:
exports.init = function() {
m_app.init({
canvas_container_id: "canvas_cont",
callback: init_cb,
physics_enabled: false,
alpha: true,
report_init_failure: false,
media_auto_activation: false
});
}
Загрузим сцену:
if (window.web_page_integration_dry_run)
m_data.load("flying_letters.json", load_cb);
else
m_data.load("/tutorials/examples/web_page_integration/flying_letters.json", load_cb);
Примечание
Проверка переменной web_page_integration_dry_run выполняется для указания пути к JSON файлу в отладочном приложении. Т. е. в нем путь к JSON файлу - "flying_letters.json", а на текущей странице - "/tutorials/examples/web_page_integration/flying_letters.json".
Ниже приводится пример добавления переменной web_page_integration_dry_run в html файл:
<script type="text/javascript">
window.web_page_integration_dry_run = true;
</script>
Добавим обработчик событий на измение размеров окна браузера. Затем принудительно вызовем функцию resize():
window.addEventListener("resize", resize);
resize();
В функция resize() используется метод resize_to_container(), который устанавливает высоту и ширину области отрисовки как и родительского контейнера:
function resize() {
m_app.resize_to_container();
}
После загрузки сцены, вызывается функция load_cb(). В ней мы останавливаем анимацию - потому что мы установили ее на автозапуск в Blender'е - и привязываем к элементу #run_button событие mousedown:
var letters_arm = m_scs.get_object_by_name('beads_armature');
m_anim.stop(letters_arm);
run_button.addEventListener("mousedown", demo_link_click, false);
При клике по элементу #run_button вызывается функция demo_link_click(). В ней мы запустим анимацию полета шаров и звук нажатия кнопки:
m_data.activate_media();
var letters_arm = m_scs.get_object_by_name('beads_armature');
var spk = m_scs.get_object_by_name("Speaker");
m_sfx.play_def(spk);
m_anim.apply(letters_arm, "flying_letters");
m_anim.play(letters_arm, letters_obj_cb);
После окончания анимации полета вызывается функция letters_obj_cb(). В ней мы запустим циклическую анимацию, чтобы шары покачивались на месте:
m_anim.apply(obj, "flying_letters_idle");
m_anim.set_behavior(obj, m_anim.AB_CYCLIC);
m_anim.play(obj);
Вот и все!
Выводы
Технология WebGL предоставляет уникальную возможность бесшовной интеграции интерактивного 3D контента с другими веб-технологиями. С помощью Blend4Web можно относительно легко создать такой контент в популярной программе Blender, разместить его на веб-страницах и объединить логикой с любыми HTML элементами.
Изменения
[2014-08-01] Изначальная публикация.
[2014-10-22] Изменены пути к файлам сцен.
[2014-10-30] Исправлены ссылки к веб-плееру в связи с изменением имени файла. Добавлен атрибут allowfullscreen. Опущен устаревший параметр bg.
[2014-12-03] Добавлен звук для кнопки.
[2015-04-23] Изменен путь к исходникам веб-плеера на GitHub. Изменены имена переменных и анимаций. Опущен параметр deferred_rendering и context_antialias в функции m_app.init().
[2015-05-15] Добавлено описание стилей приложения. Логика изменения размеров области отрисовки перенесена из скрипта в таблицу стилей. Добавлена ссылка на отладочное приложение. Добавлено описание функции resize()
[2015-12-10] Удален модуль app.js
[2017-01-12] Небольшие правки текста.