Техническая статья-инструкция для тех, кто собирается создавать контент с использованием JavaScript

У плееров SpinetiX есть одна очень привлекательная возможность, которая незаслуженно остается в тени. Речь идет об использования JavaScript при создании контента. Благодаря архитектуре плееров с его помощью можно делать много чего: импортировать данные из других систем, управлять медиа-контентом, создавать на лету элементы, менять их свойства и многое другое.

Плееры SpinetiX поддерживают стандарт ECMAScript 5 (начиная с версии прошивки 3.0.0). Поддерживается ограниченное число библиотек и API - их достаточно, для большинства задача, на которые рассчитан плеер.

Основная библиотека, которая есть в каждом проекте - это jSignage, включающая функции из jQuery (библиотека импортирована для SpinetiX OS). Кроме того, можно использовать также ограниченный набор модулей из Node API: buffer, events, net, stream и dgram.

Что потребуется для работы?

  • плеер SpinetiX HMP400 (можно и более ранние модели);
  • программа Elementi (для создания больших проектов очень желательна версия Elementi X, которая включает встроенные средства отладки, но для начала можно обойтись и Elementi S - ее вполне достаточно для освоения и создания первых проектов);
  • текстовый редактор для редактирования .js файлов;
  • знание JavaScript и умение работать в графической оболочке Elementi для создания контента.

Создаем Hello World!

Не будем нарушать традицию и создадим проект, который выводит текст: «Hello World». Это позволит понять базовые принципы, как добавлять скрипты в проект и работать с ними.

Не смотря на достаточно большие возможности по программированию Elementi не предлагает функций управления скриптами через GUI, и добавлять скрипты в проект придется вручную. Хорошая новость, что делать это нужно будет только один раз при добавлении нового скрипта.

Поехали.

Заходим в Elementi и создаем проект Hello World и сразу создадим в проекте папку scripts, в которой у нас будут храниться скрипты.

В каждом проекте у нас есть index.svg, в которым хранится вся структура нашего проекта - описание всех элементов и их атрибутов. В этот же файл мы будем добавлять информацию об используемых скриптах.

В терминах SpinetiX проект - это папка, и мы можем посмотреть ее содержание, используя Проводник.

Мы видим тут созданную пустую папку scripts и файл index.svg. Так как svg - это текстовые файлы, мы можем открыть его в текстовом редакторе. Мы видим структуру, из которой нас интересует только блок загрузки скриптов:

Скрипт 1: это загрузка основной библиотеки jSignage.
Скрипт 2: начальная инициализация слоев.

Тут стоит сказать пару слов о конструкции:

$(function(){
// ...
});

Она эквивалентна:

$('svg').ready(function(){
// ...
});

Так становится все гораздо понятнее: $('svg')m - получение корневого элемента структуры проекта, а .ready() вызывает наш callback, когда завершается строительство DOM.

Если не использовать эту обертку, то к моменту вызова нашего скрипта DOM-структура будет еще не готова, и мы не сможем с ней производить никакие операции. Иногда это не нужно, например, если скрипт делает внутреннюю инициализацию или обращается за внешними данными и не обращается к DOM.

Добавлять скрипты можно тремя способами, два из которых мы уже видели:

  • используя xlink:href (можно загружать внешние и локальные скрипты). Так, например, загружается скрипт 1 в примере выше;
  • используя inline-скрипты в svg. Мы видим это примере 2;
  • используя функцию .include в inline-скрипте.

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

Обращаю внимания, что в первом случае, скрипт не имеет обертки и поэтому в момент запуска скрипта мы не можем использовать обращения к DOM, но ничто нам не запрещает сделать обертку с .ready непосредственно в нашем скрипте - об этом речь пойдет ниже.

При использовании .include в inline-скрипте мы можем сразу обернуть его вызов и дождаться окончания строительства DOM. Это упрощает нам жизнь, поэтому в первом примере мы будем использовать .include.

В папке scripts создаем файл hello.js:

alert('Hello World');

Далее открываем в текстовом редакторе index.svg и добавляем импорт нашего файла внутри callback'а:

<script><![CDATA[
$(function(){
$.include('scripts/hello.js');
});
]]></script>

В результате должно получиться так:

Теперь, если мы перезагрузим проект в Elementi (двойное нажатие мышкой на index.svg), у нас откроется сообщение Hello World - наш скрипт загружается и запускается. Первая версия нашей программы готова.

ВАЖНОЕ ЗАМЕЧАНИЕ: мы добавили загрузку нашего скрипта непосредственно в index.svg. А что будет, если мы будем редактировать проект в Elementi? Если мы добавим элемент в GUI, то index.svg будет перезаписан. Что будет с нашим добавленным скриптом? Хорошая новость - все что мы добавляем как скрипты будет сохраняться в проекте. Поэтому, добавив скрипт один раз, нам больше не нужно ничего делать. В тоже время сам скрипт мы можем редактировать.

Hello World с созданием слоя на лету

В предыдущем примере мы научились загружать скрипты. Теперь давайте добавим отображение надписи Hello World! рендером плеера, а не функцией alert. Для этого мы модифицируем наш hello.js:

$('svg').add($.textArea({
left: 240,
top: 60,
width: 800,
height: 600,
frame: { frameColor: 'white', frameSize: 2 },
fill: '#ff0000',
fontSize: 120
}).text( 'Hello World!' ));

Если мы все сделали правильно, то у нас получится:

Мы на лету создали текстовый элемент и вывели его на экран.

Hello World - меняем текст в элементе

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

Заодно давайте посмотрим в чем разница с загрузкой скрипта с использованием xlink:href.

Удаляем строчки из index.svg:

<script><![CDATA[
$(function(){ $.include('scripts/hello.js');
});
]]></script>

И добавляем:

<script xlink:href="scripts/hello.js"/>

Замечаем, что наш пример продолжает работать. Добавляем новый текстовый слой в GUI - мы хотим изменить его текст в нашем коде. Задаем расположение и свойства, потом идем в раздел свойств Расширенные и меняем там id на hello (можем этого и не делать, но удобнее работать с понятным id).

Меняем наш hello.js:

$('#hello').text('Hello World!');

Здесь $('#hello') возвращает нам наш элемент, а text('Hello World!') меняет значение текста.

Запускаем проект и... ничего не происходит. Как я уже говорил раньше, при использовании метода загрузки через xlink:href, структура DOM не готова в момент запуска скрипта и поэтому у нас ничего не вышло.

Модифицируем наш hello.js:

$(function(){
$('#hello').ready(function(){
$('#hello').text('Hello World!');
});
});

Тут мы обернули вызов нашей инициализации в сразу два callback'а - первый дожидается, когда будет готова структура 'svg'. А второй дожидается, когда в нее будет добавлен наш элемент hello (для адресации по id элемента мы используем символ #).

Мы можем упростить наш код до:

$(function(){
$('#hello').text('Hello World!');
});

Но для этого нам нужно переместить вызов нашего скрипта после скрипта инициализации 2 - скрипты вызываются последовательно и callback'и будут вызываться в той же очередности.

Запускаем проект, и все работает:

Вместо заключения

Когда мы разобрались, как добавлять скрипты и понимаем базовые принципы, то можем начинать экспериментировать и создавать различные решения - JavaScript дает колоссальную гибкость и открывает много возможностей.

Полезные ссылки