События

Прелоадер - это просто!

2016-08-11

Итак, парни. Поднимите руку, кто не знает, что такое прелоадер. Полагаю никто не купился, а если все же чья-то дрожащая рука мелькает, то предлагаю нажать на компе кнопку Reset и полюбоваться на самый настоящий прелоадер.

Для всех остальных, кто ухмыльнулся и проигнорировал мой вредный совет, я продолжу урок.

Удивительное дело, едва программист создал свою программу, как ему хочется внедрить в нее полосу загрузки. А вдруг, кто подумает, что она банально зависла, а не качает терабайт данных из сети Интернет! Знаете, как-то приятно осознавать, что пользователь любуется ползущей полоской, а не проклинает криворуких создателей. Поэтому, давайте приступим к уроку и разберемся с этим самым прелоадером.

Теоретический ликбез

Прелоадер работает в тесной связке с загрузчиком, который в Blend4Web реализуется в виде функции load из модуля data. Обычно структура загрузчика выглядит так:

var m_data      = require("data");
var m_preloader = require("preloader");

function load() {
    m_data.load("filename.json", load_cb, preloader_cb);
}

function load_cb(data_id) {

}

function preloader_cb(percentage) {

}

Здесь функция load генерирует два события, где первое вызывается после окончании загрузки файла, а второе постоянно возвращает числовой результат процесса. Поэтому, основная работа с прелоадером концентрируется именно в обработчике события preloader_cb.

Прелоадер за две секунды

Не верите? Нам понадобятся только эти две команды:

m_preloader.create_preloader();
m_preloader.update_preloader();

Простая «полоска» за две секунды.

С их помощью можно очень быстро и без труда создать простейшую полоску загрузки. Вот рабочий пример:

var m_data      = require("data");
var m_preloader = require("preloader");

function load() {
    m_preloader.create_preloader();
    m_data.load("filename.json", load_cb, preloader_cb);
}

function load_cb(data_id) {

}

function preloader_cb(percentage) {
    m_preloader.update_preloader(percentage);
}

Включаем «форсаж»

Разработчики предусмотрели некоторые опции, которые помогут разнообразить стандартную палитру прелоадера.

Всего несколько опций и экран «расцвёл».

Для этого достаточно определить цвета в функции create_preloader():

var m_data      = require("data");
var m_preloader = require("preloader");

function load() {
    m_preloader.create_preloader({
        container_color:"#a0e5ff", // background color of the container 
        bar_color:"#fa200", // background color of the bar 
        frame_color: "#f35600", // color of the frame border
        font_color: "#000" // color of the font
    });
    m_data.load("filename.json", load_cb, preloader_cb);
}

function load_cb(data_id) {

}

function preloader_cb(percentage) {
    m_preloader.update_preloader(percentage);
}

Режим эксперта

Лучшего результата можно достичь, если сделать свой собственный прелоадер.

Экран загрузки из игры «Сказ о Пятигоре».

Несколько месяцев назад разработчики Blend4Web заявили о релизе браузерной игры «Сказ о Пятигоре». Исходники её открыты и доступны в дистрибутиве SDK. Так что вы можете не только наслаждаться интересным геймплеем и красочностью игры сделанной на Blend4Web, но и познакомиться с внутренней «кухней».

Отличным примером создания собственного прелоадера может служить соответствующий код в Пятигоре.

Основой его является всё та же схема загрузки, приведенная выше. Однако здесь не используются функции модуля preloader. Смысл заключается во взаимодействии кода на JavaScript с HTML и CSS. Давайте рассмотрим, как это работает.

Файл HTML

Канвас приложения и экран загрузки могут быть отдельными html-элементами. Собственно, так и сделано в Пятигоре. Это позволяет с легкостью управлять ими через JavaScript:

<body>
    <div id="main_canvas_container"></div>
    <div id="preloader_cont">
        <div id="prelod_static_path">
        <div id="prelod_dynamic_path"></div>
            <span>0%</span>
        </div>
    </div>
</body>

Здесь, элемент "main_canvas_container" — канвас приложения, а "preloader_cont" отвечает за экран загрузки.

Файл CSS

Конечно, стиль веб-страницы лучше всего описывать в файле CSS. Я не стану вдаваться в подробности этого процесса, а просто приведу соответствующий кусок кода, взятый из Пятигора:

div#prelod_static_path {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 395px;
    height: 134px;
    margin-left: -197px;
    margin-top: -75px;
}
div#prelod_dynamic_path {
    position: absolute;
    left: 0;
    top: 0;
    width: 0%;
    height: 100%;
    background-image: url(images/loader_bar_line.png);
}
div#preloader_cont {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    background-image: url(images/preloader_bg.jpg);
    background-color: #171717;
    background-repeat: no-repeat;
    background-position: center center;
    visibility: hidden;
}

Здесь описывается каждый графический элемент используемый в построении экрана загрузки. Обратите внимание на опцию visibility у блока #preloader_cont. Именно с его помощью можно управлять показом экрана загрузки.

Файл JavaScript

Перед выполнением загрузки активируется экран прелоадера. Функция getElementById() возвращает нужный html-элемент у которого изменяется свойство стиля visibility (см. листинг CSS).

function load() {
    var preloader_cont = document.getElementById("preloader_cont");
    preloader_cont.style.visibility = "visible";
    m_data.load("filename.json", load_cb, preloader_cb);
}

Так как функция preloader_cb возвращает процентное значение от выполненного действия, то этим можно воспользоваться, чтобы перерисовывать соответствующие области экрана.

В примере ниже, изменяется свойство width у стиля, описывающего полосу загрузки. Первоначальное значение его равно нулю, которое, в соответствии с переменной percentage, динамически изменяется. Таким же способом корректируется числовое значение результата работы.

Обратите внимание, что после завершения загрузки потребуется скрыть html-элемент preloader_cont.

function preloader_cb(percentage) {
    var prelod_dynamic_path = document.getElementById("prelod_dynamic_path");
    var percantage_num      = prelod_dynamic_path.nextElementSibling;

    prelod_dynamic_path.style.width = percentage + "%";
    percantage_num.innerHTML = percentage + "%";	   
    if (percentage == 100) {
        var preloader_cont = document.getElementById("preloader_cont");
	preloader_cont.style.visibility = "hidden";
        return;
    }
}

Это всего-лишь пример создания собственного прелоадера. Не забывайте, что используя Blend4Web, к вашим услугам остаются все возможности современных браузерных технологий: HTML5, CSS3, jQuery (дополните этот список сами). В этом и проявляется гибкость и мощь нашего любимого фреймворка. Удачи в создании крутых прелоадеров!

Комментарии
30 авг. 2016 12:45
Круть! Благодарю!
30 авг. 2016 13:31
Добрый день! У меня вопросик. А нельзя ли просто создать через редактор кода три файла: name.html, name.css, name.js ? Не генерировать name.json. В html прописать ссылки на библиотеки, в css стили, индексировать холст, и в js скрипт и на этом ограничится.
Ведь при создании проекта в Блендере генерируется 3д-сцена, а в прилоадере вроде плоский холст:)
Если можно не генерировать, то как быть с "filename.json" в сценарии? Где его взять?:)

Если я чего-то не до понял, извиняюсь:) Спасибо!
30 авг. 2016 14:29
Добрый день.

В .json-файле хранится информация об трёхмерной сцене (настройки и т.д.). Он получается при экспорте (вместе с .bin-файлом, в котором хранится геометрия объектов). Таким образом, .json-файл получается экпортом из Blender'a.

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

Если вас запутала информация об экспорте сцены в json - то об этом можно почитать тут.

А нельзя ли просто создать через редактор кода три файла: name.html, name.css, name.js ? Не генерировать name.json. В html прописать ссылки на библиотеки, в css стили, индексировать холст, и в js скрипт и на этом ограничится.

А вообще я так всегда и делаю. Ну и еще как раз вам понадобятся два файла - scene_name.json и scene_name.bin, получаемые при экспорте (ну и сам движок вам тоже понадобится, процесс создания своего приложения описан тут)
21 сен. 2016 11:25
Добрый день,

У меня заработал вариант с create_simple_preloader(). С create_preloader проект отказывался загружаться.
27 сен. 2016 13:58
С create_preloader проект отказывался загружаться.
Т.е. вариант указанный в статье у вас не заработал?

var m_data      = require("data");
var m_preloader = require("preloader");

function load() {
    m_preloader.create_preloader();
    m_data.load("filename.json", load_cb, preloader_cb);
}

function load_cb(data_id) {

}

function preloader_cb(percentage) {
    m_preloader.update_preloader(percentage);
}


А что в консоли то выводилось?
19 дек. 2016 09:18
Доброго времени суток, при использовании метода m_preloader.create_preloader(); в консоли ошибка:

При попытке использовать метод create_simple_preloader() в консоли куча ошибок вида:

Пытался сделать как в примерах, ничего не получилось…
Файл проекта прикрепляю.
19 дек. 2016 14:21
Спасибо, приятно и просто "разжевали" ..
все не доходило дело вникнуть как кастомный прелоадер делать
и вот … буду пробовать

а то я тут пробовал поиграться со стандартным
https://www.blend4web.com/ru/forums/topic/2813/
19 дек. 2016 14:37
Доброго времени суток, при использовании метода m_preloader.create_preloader(); в консоли ошибка:

При попытке использовать метод create_simple_preloader() в консоли куча ошибок вида:

Пытался сделать как в примерах, ничего не получилось…
Файл проекта прикрепляю.
Добрый день!

У Вас функция preloader_cb объявлена вне модуля основного приложения. Если переместить ее внутрь, то все должно работать как положено
19 дек. 2016 15:05
У Вас функция preloader_cb объявлена вне модуля основного приложения. Если переместить ее внутрь, то все должно работать как положено
Благодарю, вопрос снимается, разобрался)
19 дек. 2016 21:57
вопрос по старому круговому прелоадеру?
его то как можно использовать, а то так уж получается, что он мне очень подходит,
еще бы мне его кастомизировать)))
Пожалуйста, зарегистрируйтесь или войдите под своей учетной записью , чтобы оставлять сообщения.