Принято считать, что Blockly является инструментом для обучения детей основам программирования при помощи блоков. Он действительно ориентирован для использования в учебных целях, но по существу представляет собой визуальный редактор кода для языков программирования JavaScript, Python, PHP, Lua и Dart. Другими словами, это конфигурируемая платформа, которую можно использовать для решения разных задач. Например, Blockly используется для создания мобильных приложений под iOS и Android на платформе Thunkable X. Мы не будем изучать программирование на Blockly, но рассмотрим возможности данной платформы с позиции разработчика визуальных инструментов программирования. Эти знания помогут лучше и глубже понять любое приложение и проект, где используется Blockly, будь то инструмент для создания игр, управления роботом или что-то ещё. Для начала подключит редактор на web-страницу и произведём его настройку, что происходит очень просто.
Скачайте исходники Blockly. После этого создайте пустую web-страницу, в заголовке которой подключите библиотеку ядра редактора, основных блоков и сообщений.
<script src="blockly_compressed.js"></script> - импорт библиотеки ядра Blockly
<script src="blocks_compressed.js"></script> - импорт библиотеки основных блоков
<script src="msg/js/en.js"></script> - импорт библиотеки сообщений (на английском языке)
Для смены языка сообщений перейдите в директорию msg/js/, найдите нужный файл и укажите его название вместо en.js.
В теле страницы создайте элемент для области редактора и укажите его размер:
<div id="blocklyDiv" style="height: 300px; width: 400px;"></div>
Область редактора включает в себя панель инструментов и рабочее поле. Ширина рабочего поля в нашем случае будет равна:
ширина рабочего поля =
ширина области редактора (400 px) - ширина панели инструментов.
Панель инструментов можно создать при помощи дерева XML:
<xml id="toolbox" style="display: none">
<block type="controls_if"></block>
<block type="controls_repeat_ext" disabled="true"></block>
</xml>
или в строковом представлении:
<script>
var toolbox = '<xml>';
toolbox += ' <block type="controls_if"></block>';
toolbox += ' <block type="controls_repeat_ext" disabled="true"></block>';
toolbox += '</xml>';
</script>
Блоки задаются элементом <block> и имеют следующие атрибуты:
После создания панели инструментов её нужно добавить в область редактора при помощи метода Blockly.inject:
<script>
var workspacePlayground = Blockly.inject('blocklyDiv',
{toolbox: document.getElementById('toolbox')});
</script>
или:
<script>
var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
</script>
для второго случая.
В результате получится простой редактор.
Для дальнейшей работы удобно использовать какую-нибудь среду web-разработки, например, jsFiddle, CodePen и т.п., в которой можно будет сразу видеть результат работы кода и быстро настраивать область редактора.
Панель инструментов и рабочее поле можно настроить необходимым образом. В нашем примере рабочее поле имеет фиксированный размер, но можно сделать так, чтобы оно занимало всю доступную область страницы. В официальной документации содержится ошибка, из-за которой при измененни размера окна рабочее поле иногда масшабируется некорректно. Для исправления ошибки в конец функции обработчки события onresize добавьте строку:
Blockly.svgResize(workspacePlayground);
Панель инструментов может находиться в одном из двух режимов - без отображения категорий и с отображением категорий. В примере выше панель инструментов находится в режиме без отображения категорий. Этот режим используется при работе с небольшим количеством блоков. При работе с большим количеством блоков используется второй режим, который позволяет распределить блоки по категориям для более быстрой и удобной работы с ними.
Для настройки панели инструментов и рабочего поля используются следующие пары имя-значение:
collapse: | boolean | Позволяет сворачивать и разворачивать блоки (соответствующая команда добавляется в контекстное меню блоков). По умолчанию равно true, если панель инструментов имеет категории и false в противном случае. |
comments: | boolean | Позволяет блокам иметь комментарии. По умолчанию установлено в true, если панель инструментов содержит категории или false в противном случае |
css: | boolean | Если равно false, не используется CSS (стили CSS в этом случае задаются документом). По умолчанию равно true. |
disable: | boolean | Позволяет сделать блоки недоступными для выбора. По умолчанию равно true, если панель инструментов имеет категории или false в противном случае. |
grid: | object | Управляет параметрами сетки, к которой блоки могут быть привязаны. |
horizontalLayout: | boolean | В случае true панель инструментов в области редактора располагается горизонтально, в случае false - вертикально. По умолчанию установлено в false. |
maxBlocks: | number | Задаёт максимальное количество блоков, которое можно создать в редакторе. По умолчанию равно бесконечности. |
media: | string | Задаёт путь к медиа директории Blockly. По умолчанию установлен путь "https://blockly-demo.appspot.com/static/media/". |
oneBasedIndex: | boolean | В случае true индексация списков и строк начинается от 1, если false - индексация от 0. По умолчанию true. |
readOnly: | boolean | Если true запрещает пользовательское редактирование. В этом режиме панель инструментов и мусорная корзина не отображаются. По умолчанию false. |
rtl: | boolean | Если true отображает область редактирования зеркально (для языков справа налево). По умолчанию false. |
scrollbars: | boolean | Управляет отображение полос прокрутки в рабочем поле. По умолчанию true, если панель инструментов имеет категории и false в противном случае. |
sounds: | boolean | Если false, то при выделении и удалении блоков на рабочем поле или при выполнении ошибочного действия звуки не воспроизводятся. По умолчанию true. |
toolbox: | XML nodes or string | Поле для ссылки на древовидную или строковую структуру категорий и блоков |
toolboxPosition: | string | Если равно "start", то панель инструментов располагается сверху при горизонтальном или слева при левостороннем вертикальном положении или справа при правостороннем вертикальном расположении. Если "end", то панель инструментов располагается на противоположных сторонах. По умолчанию "start". |
trashcan: | boolean | Управляет отображением мусорной корзины. По умолчанию true, если панель инструментов имеет категории или false в противном случае. |
zoom: | object | Управляет настройками управления масштабом рабочего поля. |
Эти пары добавляются в метод Blockly.inject:
<script> var workspacePlayground = Blockly.inject('blocklyDiv',
{ toolbox: document.getElementById('toolbox'), maxBlocks: 15, trashcan: false }); </script>
Настройка панели инструментов
На панели инструментов Blockly могут располагаться:
Для создания категории предназначен элемент <category>:
<xml id="toolbox" style="display: none"> <category name="Control" colour="210"> <block type="controls_if"></block> <block type="controls_whileUntil"></block> </category> <category name="Variables" custom="VARIABLE"></category>
<category name="Functions" custom="PROCEDURE"></category> </xml>
Категории "Variables" и "Functions" обладают особым динамическим поведением. Их содержимое будет изменяться по мере создания новых блоков переменных и функций.
Элементы категорий имеют следующие атрибуты:
Использование категорий изменяет внешний вид области редактора. Появляется корзина и полосы прокрутки для рабочей области, которая становится бесконечной.
Категории могут быть вложенными:
<xml id="toolbox" style="display: none">
<category name="Core">
<category name="Control">
<block type="controls_if"></block>
<block type="controls_whileUntil"></block>
</category>
<category name="Logic">
<block type="logic_compare"></block>
<block type="logic_operation"></block>
<block type="logic_boolean"></block>
</category>
</category>
</xml>
Вложенные категорий помечаются чёрным треугольником.
В категориях могут отображаться как отдельные блоки, так и группа блоков.
<xml id="toolbox" style="display: none">
<block type="logic_boolean"></block>
<block type="math_number">
<field name="NUM">42</field>
</block>
<block type="controls_for">
<value name="FROM">
<block type="math_number">
<field name="NUM">1</field>
</block>
</value>
<value name="TO">
<block type="math_number">
<field name="NUM">10</field>
</block>
</value>
<value name="BY">
<block type="math_number">
<field name="NUM">1</field>
</block>
</value>
</block>
<block type="math_arithmetic">
<field name="OP">ADD</field>
<value name="A">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="B">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
</block>
</xml>
Блоки без параметров имеют поле <field>, в котором указывается значение для блока. В блоках с параметрами нужный параметр указывается при помощи элемента <value>.
В блоках с параметрами можно использовать как обычные, так и теневые блоки <shadow>. Теневые блоки используются для непосредственного ввода значений и для указания значения по умолчанию, что помогает определить тип параметра. Теневой блок заменяется обычным блоком, если последний расположить над ним.
Для отделения категорий или блоков друг от друга используются разделители <sep></sep>:
<xml id="toolbox" style="display: none">
<block type="math_number"></block>
<sep gap="32"></sep>
<block type="math_arithmetic">
<field name="OP">ADD</field>
</block>
<sep gap="8"></sep>
<block type="math_arithmetic">
<field name="OP">MINUS</field>
</block>
</xml>
При помощи атрибута gap задаётся величина зазора между элементами в пикселях.
Помимо категорий и блоков на панели инструментов можно располагать надписи и кнопки:
<xml id="toolbox" style="display: none">
<block type="logic_operation"></block>
<label text="A label" web-class="myLabelStyle"></label>
<label text="Another label"></label>
<block type="logic_negate"></block>
<button text="A button" callbackKey="myFirstButtonPressed"></button>
<block type="logic_boolean"></block>
</xml>
<style>
.myLabelStyle>.blocklyFlyoutLabelText {
font-style: italic;
fill: green;
}
</style>
Для обработки события нажатия на кнопку используется функция обратного вызова вида:
yourWorkspace.registerButtonCallback( yourCallbackKey, yourFunction )
,где yourCallbackKey - ключ обратного вызова кнопки yourFunction - функция обратного вызова
Для программного изменения содержимого панели инструментов используется вызов функции:
workspace.updateToolbox(newTree);
newTree может быть деревом XML или иметь строковое представление, но изменить режим панели нельзя. Если изначально она работала в режиме отображения категорий, то после изменения содержимого панели она также должна иметь режим отображения категорий.
Настройка рабочего поля
Настройка рабочего поля заключается в редактировании параметров отображения сетки и привязки к ней, настройки параметров масштабирования и определение режима отображения мусорной корзины.
var workspace = Blockly.inject('blocklyDiv',
{toolbox: document.getElementById('toolbox'),
grid:
{spacing: 20, // расстояние между элементами сетки
length: 3, // размер элементов сетки
colour: '#ccc', // цвет сетки
snap: true}, // режим привязки к сетке zoom:
{controls: true, // режим отображения элементов управления масштабом
wheel: true, // режим использования колеса мыши для масштабирования
startScale: 1.0, // начальный масштаб
maxScale: 3, // максимально возможное увеличение
minScale: 0.3, // минимально возможное уменьшение
scaleSpeed: 1.2}, // шаг изменения масштаба
trashcan: true}); // режим отображения мусорной корзины
Теперь вы можете без труда разобраться с редактором Blockly в любом проекте и даже создать его самостоятельно на своей странице. После этого можно перейти к работе в нём и созданию собственных блоков.