Создание интерактивного веб-приложения
С помощью движка Blend4Web можно создавать как простые, так и относительно сложные, насыщенные интерактивные веб-приложения. Рассмотрим создание простого приложения с использованием API Blend4Web, в котором реализуем взаимодействие с объектами 3D-сцены, например, анимируя объект при выделении его мышью.
Создание нового приложения
Для создания нового приложения следует воспользоваться менеджером проектов, входящим в состав Blend4Web SDK. Для этого требуется сначала запустить Blender (с установленным аддоном), а затем зайти на главную страницу SDK по адресу http://localhost:6687/. Там менеджер проектов будет доступен по соответствующей ссылке:
Далее следует выбрать Create New Project :
Далее нужно будет выбрать имя нового проекта, к примеру, «simple_app». В случае, если вдруг проект с таким именем уже существует, будет предложено ввести другое имя. Также можно ввести отображаемый в браузере заголовок приложения, например, «Interactive Web Application»:
Остальные настройки оставим по умолчанию. После этого нажмем кнопку Create Project внизу данной страницы для создания приложения. Затем необходимо дождаться завершения и нажать Back to Projects :
Она вернет нас на страницу менеджера проектов, из которой можно открыть новое приложение по ссылке:
В результате мы увидим базовую сцену с простым кубиком:
Созданное нами приложение расположено внутри SDK по пути ./projects/simple_app/ . Теперь, когда каркас проекта готов, можно приступать к созданию 3D-сцены и написанию логики приложения.
Подготовка и экспорт 3D-сцены
Blend-файл с базовой сценой находится в директории проекта: ./projects/simple_app/simple_app.blend . Откроем его в Блендере и вместо того, что есть по умолчанию, создадим в нем сцену с объектами, источником освещения и камерой.
Для каждого из «интерактивных» объектов сделаем простую анимацию перемещения, поворота (в режимах XYZ Euler либо Quaternion WXYZ ) или масштабирования.
Также включим им опцию Selectable во вкладке Object->Selection and Outlining . Это сделает объекты доступными для выбора при клике по ним мышью.
Настроив по вкусу камеру, освещение и материалы объектов, экспортируем сцену через команду меню File -> Export -> Blend4Web (.json) . Путь экспорта следует указать таким: ./projects/simple_app/assets/simple_app.json .
Добавление функционала
В директории проекта ./projects/simple_app/ в числе других будет находиться главный JS-файл приложения simple_app.js , содержащий шаблонный код. В нем и будем реализовывать простое взаимодействие пользователя с загруженной сценой.
Для реализации задуманного функционала нам понадобятся дополнительные модули:
— animation.js — предоставляет API для управления анимацией объектов
— container.js — методы, относящиеся к Canvas-элементу и его родительскому HTML-элементу
— mouse.js — содержит ряд полезных методов, относящихся к мыши
— scenes.js — API для доступа к объектам сцены
Добавим их подключение в самом начале скрипта к остальным модулям:
// import modules used by the app var m_app = require("app"); var m_cfg = require("config"); var m_data = require("data"); var m_preloader = require("preloader"); var m_ver = require("version"); var m_anim = require("animation"); var m_cont = require("container"); var m_mouse = require("mouse"); var m_scenes = require("scenes");
В нашем примере по клику на объекте должна воспроизводиться его анимация, также будем и отменять анимацию у предыдущего выделенного объекта. Для этого в конец функции load_cb() добавим обработчик события «mousedown» для нажатий мышью по элементу Canvas. Также при необходимости можно добавить обработчик «touchstart» для нажатий на сенсорном экране:
function load_cb(data_id, success) < . var canvas_elem = m_cont.get_canvas(); canvas_elem.addEventListener("mousedown", main_canvas_click, false); canvas_elem.addEventListener("touchstart", main_canvas_click, false); >
Далее напишем соответствующую функцию-обработчик main_canvas_click() :
function main_canvas_click(e) < if (e.preventDefault) e.preventDefault(); var x = m_mouse.get_coords_x(e); var y = m_mouse.get_coords_y(e); var obj = m_scenes.pick_object(x, y); if (obj) < if (_previous_selected_obj) < m_anim.stop(_previous_selected_obj); m_anim.set_frame(_previous_selected_obj, 0); > _previous_selected_obj = obj; m_anim.apply_def(obj); m_anim.play(obj); > >
Основная логика приложения содержится именно в ней. Алгоритм в общих чертах будет следующим:
1) Получение объекта сцены, который находился под курсором.
var x = m_mouse.get_coords_x(e); var y = m_mouse.get_coords_y(e); var obj = m_scenes.pick_object(x, y);
2) Отмена анимации у предыдущего выделенного объекта.
m_anim.stop(_previous_selected_obj);
И выставление нулевого кадра, т.е. возвращение к первоначальному положению:
m_anim.set_frame(_previous_selected_obj, 0);
Для сохранения предыдущего объекта использована глобальная переменная _previous_selected_obj . Её нужно объявить где-либо, например, сразу после подключения модулей следующим образом:
var _previous_selected_obj = null;
3) Применение анимации к объекту.
Загрузка и расчет анимации, назначенной на объект в Blender’е:
Приведём код получившегося приложения целиком:
"use strict" // register the application module b4w.register("simple_app_main", function(exports, require) < // import modules used by the app var m_app = require("app"); var m_cfg = require("config"); var m_data = require("data"); var m_preloader = require("preloader"); var m_ver = require("version"); var m_anim = require("animation"); var m_cont = require("container"); var m_mouse = require("mouse"); var m_scenes = require("scenes"); var _previous_selected_obj = null; // detect application mode var DEBUG = (m_ver.type() == "DEBUG"); // automatically detect assets path var APP_ASSETS_PATH = m_cfg.get_assets_path("simple_app"); /** * export the method to initialize the app (called at the bottom of this file) */ exports.init = function() < m_app.init(< canvas_container_id: "main_canvas_container", callback: init_cb, show_fps: DEBUG, console_verbose: DEBUG, autoresize: true >); > /** * callback executed when the app is initialized */ function init_cb(canvas_elem, success) < if (!success) < console.log("b4w init failure"); return; > m_preloader.create_preloader(); // ignore right-click on the canvas element canvas_elem.oncontextmenu = function(e) < e.preventDefault(); e.stopPropagation(); return false; >; load(); > /** * load the scene data */ function load() < m_data.load(APP_ASSETS_PATH + "simple_app.json", load_cb, preloader_cb); > /** * update the app's preloader */ function preloader_cb(percentage) < m_preloader.update_preloader(percentage); >/** * callback executed when the scene data is loaded */ function load_cb(data_id, success) < if (!success) < console.log("b4w load failure"); return; > m_app.enable_camera_controls(); // place your code here var canvas_elem = m_cont.get_canvas(); canvas_elem.addEventListener("mousedown", main_canvas_click, false); canvas_elem.addEventListener("touchstart", main_canvas_click, false); > function main_canvas_click(e) < if (e.preventDefault) e.preventDefault(); var x = m_mouse.get_coords_x(e); var y = m_mouse.get_coords_y(e); var obj = m_scenes.pick_object(x, y); if (obj) < if (_previous_selected_obj) < m_anim.stop(_previous_selected_obj); m_anim.set_frame(_previous_selected_obj, 0); > _previous_selected_obj = obj; m_anim.apply_def(obj); m_anim.play(obj); > > >); // import the app module and start the app by calling the init method b4w.require("simple_app_main").init();
Веб-приложение, разобранное в статье, является простым, но в то же время интерактивным. Это минимальный пример того, что позволяет движок Blend4Web и его API.
Исходные файлы приложения и сцены находятся в составе бесплатного дистрибутива Blend4Web SDK по пути ./projects/simple_app/ .