Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Blocklyでオリジナルのビジュアル開発環境を作る手順

More than 1 year has passed since last update.

はじめに

Google が公開しているオープンソースビジュアルプログラミング環境の Blockly をカスタマイズして、オリジナルの開発環境を作っていく手順をまとめました。

同時に、GitHubでプルリクベースの開発の流れも含めてまとめています。

出来る限り前提知識なしでもわかるよう手順を省略せずに書いています。

使用した環境

  • Mac Book Pro 2017
    • Core i5 3.1GHz
    • 16GB
    • MacOS Catalina 10.15
  • Visual Studio Code 1.39.2
  • GitHub Free
  • Chrome 77.0.3865.120

GitHub にサインイン

  • GitHub にサインインします。(アカウントがない場合はサインアップします。 → Create an account)

https://github.com/login
image.png

BlocklyのソースをGitHubからクローンする

  • Visual Studio Code を起動し、ターミナルを開きます。
    image.png

  • git clone https://github.com/google/blockly.git と入力しEnterで実行します
    image.png

デモファイルを開き動作確認

  • 左上の紙が重なったアイコンをクリックし、Open Folder ボタンを押します。
    image.png

  • blocklyフォルダを選択して開きます。
    image.png

  • demos/fixed/index.html を開きます。
    image.png

  • ブラウザで開けるように拡張機能 Open in Browser をインストールします。
    (左の縦に並んでいるアイコンの3つの□がつながっているものをクリックし、open in browser で検索して install ボタンを押す)
    image.png

  • 再度index.htmlのファイルを表示し、 option + B キーを押すとブラウザが起動します。
    image.png

  • ブロックをドラッグして操作できることを確認します。
    image.png

index.htmlの中身は次のようになっています。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Blockly Demo: Fixed Blockly</title>
  <script src="../../blockly_compressed.js"></script>
  <script src="../../blocks_compressed.js"></script>
  <script src="../../msg/js/en.js"></script>
  <style>
    body {
      background-color: #fff;
      font-family: sans-serif;
    }
    h1 {
      font-weight: normal;
      font-size: 140%;
    }
  </style>
</head>
<body>
  <h1><a href="https://developers.google.com/blockly/">Blockly</a> &gt;
    <a href="../index.html">Demos</a> &gt; Fixed Blockly</h1>

  <p>This is a simple demo of injecting Blockly into a fixed-sized 'div' element.</p>

  <p>&rarr; More info on <a href="https://developers.google.com/blockly/guides/configure-blockly/web/fixed-size">injecting fixed-sized Blockly</a>&hellip;</p>

  <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>

  <xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
    <block type="controls_if"></block>
    <block type="logic_compare"></block>
    <block type="controls_repeat_ext"></block>
    <block type="math_number">
      <field name="NUM">123</field>
    </block>
    <block type="math_arithmetic"></block>
    <block type="text"></block>
    <block type="text_print"></block>
  </xml>

  <script>
    var demoWorkspace = Blockly.inject('blocklyDiv',
        {media: '../../media/',
         toolbox: document.getElementById('toolbox')});
  </script>

</body>
</html>

動作させるために必要なファイルは、
blockly_compressed.js
blocks_compressed.js
msg/js/en.js
mediaフォルダ配下のファイル
のようです。

これをコピーしてカスタマイズしていけばよさそうです。

リポジトリの作成

  • 右上の+ボタンを押して、新規リポジトリ(New repository)を選択します。
    image.png

  • リポジトリ名(Repository name)を入力して(my-blocklyとしました)リポジトリ作成(Create Repository)ボタンを押します。
    image.png

  • リポジトリが作成できました。
    image.png

作業用リポジトリの作成

  • GitHubにログインして my-blocky というリポジトリを作ります。

image.png
クローン用のURLをコピーしておいてください。

作業用リポジトリでの開発準備

  • Visual Studio Code で File / New Window で新しいウインドウを表示します。
    image.png

  • control + ` でターミナルを表示して、git clone コピーしたURL で my-blocky リポジトリをクローンします。
    image.png

  • Open Folder ボタンを押して my-blockly フォルダを開きます。
    image.png
    image.png

  • ファイルを作成します。(紙に+マークが付いたボタンを押します)
    image.png

  • ファイル名を index.html としてEnterで確定します。
    image.png

  • デモの index.html から必要な部分を、作成した index.html に持ってきます。
    持ってきた内容は次の通りです。

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Blockly Demo: Fixed Blockly</title>
    <script src="blockly_compressed.js"></script>
    <script src="blocks_compressed.js"></script>
    <script src="en.js"></script>
</head>

<body>
    <div id="blocklyDiv" style="height: 480px; width: 600px;"></div>

    <xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
        <block type="controls_if"></block>
        <block type="logic_compare"></block>
        <block type="controls_repeat_ext"></block>
        <block type="math_number">
            <field name="NUM">123</field>
        </block>
        <block type="math_arithmetic"></block>
        <block type="text"></block>
        <block type="text_print"></block>
    </xml>

    <script>
        var demoWorkspace = Blockly.inject('blocklyDiv',
            {
                media: 'media/',
                toolbox: document.getElementById('toolbox')
            });
    </script>
</body>

</html>
  • ターミナルで必要ファイルを blockly のフォルダから my-blockly のフォルダにコピーします。
cp ../blockly/blockly_compressed.js .
cp ../blockly/blocks_compressed.js .
cp ../blockly/msg/js/en.js .
cp -r ../blockly/media media/
  • 保存してから option + b キーを押してブラウザで動作を確認しましょう。 image.png

一旦動く形にできたので、プルリクを作ってコミットします。

ブランチを作成してコミット

  • 左下の master という部分をクリックして、 create new branch を選択します。
    image.png

  • ブランチ名を入力しEnterで確定します。今回は add_minimum_runtime としました。
    image.png
    ※左下の表示が master から add_minimum_runtime に切り替わります。

  • Gitに切り替えます。(左の縦に並んでいる丸が3つ線で繋がっているアイコンをクリック)
    image.png

  • 左上の入力欄にコミットコメントを入力します。今回は「最小限の実行環境作成」としました。
    image.png

  • command + Enter でコミットします。
    image.png
    ※ git add していないので確認を求められますが、全てのファイルをコミットするので、Yes を選択します。

GitHubにプッシュ

・・・のボタンをクリックして、Pushを選択します。
image.png

  • GitHub上に add_minimun_runtime というブランチがないため、確認を求められますが、今回作成するので OK を選択します。
    image.png

  • GitHub にログインするためのユーザIDとパスワードを入力します。(既に入力済みの場合は出ない、2段階認証している場合はパスワードにトークンを入力)
    image.png

  • 右下で下のような確認がでたら、Noを選択します。(手動でgit fetchをするため)
    image.png

  • プッシュが成功しているかどうかGitHubで確認します。
    image.png
    ※黄色の背景にプッシュ下ブランチが表示されていれば成功です。

  • プルリクエストを出す

緑のボタン(Compare & pull request)を押します。
image.png
Writeの枠内には内容をチェックする人に伝えたい内容を入れますが、今回は自分なので空欄のままにして、Create pull request ボタンを押します。

  • master にマージする image.png CommitsやFiles changedタブの内容を見ておかしな変更がないかを確認してOKなら Merge pull request ボタンを押します。(もし問題があればWriteに指摘内容を記入して Comment ボタンを押します。その後修正をプッシュして再度確認という流れになります)

Confirm merge ボタンを押すとマージ完了です
image.png

image.png

  • ローカルブランチをmasterに戻してGitHubと同期する image.png
    • 左下の add_minimum_runtime をクリックして、master を選択します。
    • master の右にある矢印が丸くなったマークをクリックして同期します。 image.png 確認が出た場合は、OK を押します。 image.png

日本語化してみる

blockly の msg/jsフォルダ内に ja.js ファイルがあり、日本語の内容が入っているようです。先ほど使った en.js を ja.js に置き換えて日本語に変えてみましょう。

ブランチを作成

  • 先ほどと同じ要領で change_japanese というブランチを作成します。
    image.png

  • 日本語ファイル ja.js をコピーする

cp ../blockly/msg/js/ja.js .
  • 読み込むファイルを en.js から ja.js に切り替える
    image.png

  • ブラウザで確認します。
    image.png
    日本語になってますね

  • コミットからプルリク、マージまで実施します。
    image.png
    image.png
    image.png


いろいろなカスタマイズ

blocklyフォルダ内の demos/index.html を開くと、いろいろなデモの一覧が確認できます。
image.png

これらを参考にしながら、カスタマイズしていきます。

全画面表示にする

image.png
Resizable blockly のデモを参考にします。
https://developers.google.com/blockly/guides/configure/web/resizable
をみると、HTML内の BlocklyDiv を BlocklyArea で囲んで window のリサイズイベントを設定するようです。

うまくいかなかったので、position: fixed を使う形で実装しました。
image.png

変更内容は以下で確認できます。
https://github.com/nakazawaken1/my-blockly/pull/3/files

ブロックと連動した JavaScript等のコードを表示する

image.png

組み立てたブロックをJavaScriptプログラムとして取り出すには
javascript_compressed.js
を追加で読み込み、
Blockly.JavaScript.workspaceToCode(workspace)
とすると戻り値として、JavaScriptのソースが返ります。

https://developers.google.com/blockly/guides/configure/web/code-generators
にある通り、他の言語として、現状python、php、lua、dartに対応しています。
blockly/generatorsフォルダにそれぞれの元になるファイルが格納されています。
他の言語でもこれらに対応するファイルを自分で用意すれば対応可能のようです。

コードに変換するタミングをブロックが変更されたときにしたいので、調べてみると
workspace.addChangeListener で登録した処理がブロック変更時に呼ばれるようです。

以下のようにして変更時にソースを更新するようにしました。

        var source = document.getElementById('source'); //ソース表示先
        var language = document.getElementById('language'); //言語選択のselectタグ
        var task = null; //1秒以内の連続実行を抑制
        var updatePreview = function () { //ソースコード更新
            if (task != null) clearTimeout(task);
            task = setTimeout(function () {
                source.textContent = Blockly[language.value].workspaceToCode(workspace);
            }, 1000);
        };
        workspace.addChangeListener(updatePreview); //ブロックが変更された時ソースコード更新
        language.addEventListener('change', updatePreview, false); //言語を切り替えた時ソースコード更新

add_preview というブランチを作り、表示処理を実装しました。
https://github.com/nakazawaken1/my-blockly/pull/4/files
image.png
image.png

使用するブロックのみ表示する

今までデモで用意されてきたブロックのまま進めてきましたが、必要ないブロックを消したり、他のブロックを表示する方法を確認します。

image.png
今の状態だと上から、条件分岐、比較演算、繰り返し、数値、数値計算、文字列、出力が表示されています。
対応するソースは以下になっています。

<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
    <block type="controls_if"></block>
    <block type="logic_compare"></block>
    <block type="controls_repeat_ext"></block>
    <block type="math_number">
        <field name="NUM">123</field>
    </block>
    <block type="math_arithmetic"></block>
    <block type="text"></block>
    <block type="text_print"></block>
</xml>

子供に数字の演算だけをさせたいというときなどは数値、数値計算、出力があればよさそうです。

<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
    <block type="math_number">
        <field name="NUM">1</field>
    </block>
    <block type="math_arithmetic"></block>
    <block type="text_print"></block>
</xml>

こうすれば3つのみの表示になります。
image.png

ブロックを種類(カテゴリ)分けする

デモに入っていないブロックもたくさん定義されていて、
https://github.com/google/blockly/wiki
に英語ですが分類別に紹介されています。

ちなみに、ブロックを分類ごとに分けて表示するには、blockタグをcategoryタグで囲むようです。
name属性で分類名、colour属性で色を指定できます。colorではないので注意してください。
利用者側で作れるブロックである変数、関数を使用する際はcustom属性にそれぞれ、VARIABLE、PROCEDUREを指定するようです。
あと、 expanded="true"をつけると展開した状態で起動します。ただし、blockを囲むカテゴリは同時には複数展開できないようです。

<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
    <category name="制御構造" expanded="true">
        <category name="条件" colour="%{BKY_LOGIC_HUE}">
            <block type="controls_if"></block>
            <block type="logic_compare"></block>
        </category>
        <category name="繰り返し" colour="%{BKY_LOOPS_HUE}">
            <block type="controls_repeat_ext"></block>
        </category>
    </category>
    <category name="数値" colour="%{BKY_MATH_HUE}" expanded="true">
        <block type="math_number">
            <field name="NUM">1</field>
        </block>
        <block type="math_arithmetic"></block>
    </category>
    <category name="文字" colour="%{BKY_TEXTS_HUE}">
        <block type="text"></block>
        <block type="text_print"></block>
        <block type="string_length"></block>
    </category>
    <category name="変数" colour="%{BKY_VARIABLES_HUE}" custom="VARIABLE">
    </category>
    <category name="関数" colour="%{BKY_PROCEDURES_HUE}" custom="PROCEDURE">
    </category>
</xml>

と書くと以下のような表示となります。
image.png

カテゴリタグをつけると画面右下にゴミ箱が出てきて、ブロックを置く領域がスクロールできるようになります。

色の指定方法

colour="%{BKY_LOGIC_HUE}"のように色を指定していますが、
色は0〜360で指定するHSVカラーモデルという仕組みを使っているようです。
image.png
https://developers.google.com/blockly/guides/create-custom-blocks/block-colour

もともと用意されているブロックの色と合わすために、定数が定義されています。

BKY_LOGIC_HUE
BKY_LOOPS_HUE
BKY_MATH_HUE
BKY_TEXTS_HUE
BKY_LISTS_HUE
BKY_COLOUR_HUE
BKY_VARIABLES_HUE
BKY_VARIABLES_DYNAMIC_HUE
BKY_PROCEDURES_HUE

実際の数字は ja.js 内に定義されていました。

Blockly.Msg["MATH_HUE"] = "230";
Blockly.Msg["LOOPS_HUE"] = "120";
Blockly.Msg["LISTS_HUE"] = "260";
Blockly.Msg["LOGIC_HUE"] = "210";
Blockly.Msg["VARIABLES_HUE"] = "330";
Blockly.Msg["TEXTS_HUE"] = "160";
Blockly.Msg["PROCEDURES_HUE"] = "290";
Blockly.Msg["COLOUR_HUE"] = "20";
Blockly.Msg["VARIABLES_DYNAMIC_HUE"] = "310";

BKY_は自動的に付加されるようです。

枠線(グリッド)を表示する

workspace を作成する Blockly.inject の第二引数で、grid を設定することで枠線を表示できます。

var workspace = Blockly.inject('blocklyDiv',
    {
        media: 'media/',
        toolbox: document.getElementById('toolbox'),
        grid:
        {
            spacing: 12, //間隔
            length: 12, //線の長さ
            colour: '#eee', //線の色
            snap: true //ブロックを
        },
    });

image.png
spacing はマス目の大きさ、length は線の長さで小さい値にするとマス目ではなく点になります。
length: 2で下記のようになります。
image.png

いろいろな設定を変えてみる

Blockly.inject の第二引数で様々な設定ができるようです。
https://developers.google.com/blockly/guides/get-started/web#configuration

  • ゴミ箱は trashcan: true で表示、false で非表示

  • ブロックの大きさを変えるのは zoom
    image.png

zoom:
{
    controls: true, //拡大、縮小、元のサイズボタンを表示
    wheel: true, // マウスホイールでの拡大縮小有効
    startScale: 3.0, //初期倍率
    maxScale: 3, //最大倍率
    minScale: 0.3, //最小倍率
    scaleSpeed: 1.2 //ズームするスピード
}
  • ブロックが並んでいる部分をツールボックスと呼ぶようで、その配置を変えるのが horizontalLayout と toolboxPosition です。

既定値の horizontalLayout:false, toolboxPosition:'start' で左、
horizontalLayout:false, toolboxPosition:'end' で右、
horizontalLayout:true, toolboxPosition:'start' で上、
horizontalLayout:true, toolboxPosition:'end' で下に配置できます。(下記画像)
image.png

  • scrollbars: true でカテゴリタグがなくてもスクロール可能となり、falseで不可となります。

ここまでの内容を含めたプルリクを作成しました。
https://github.com/nakazawaken1/my-blockly/pull/5/files


...以下作成中

新しいブロックを定義する

プログラムを初期表示する

使えるブロックの数を制限する

ブロックをハイライトしながらステップ実行する

作成内容の保存、復元

ブロックの大きさを変える

eys-style
人生を豊かにする仲間と文化・芸術を慈しみながら生きるコミュニティをテクノロジーで実現する。
http://eys-style.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away