Blocklyでスライダー入力を行う


## Blocklyとは

https://developers.google.com/blockly

Googleの開発している、ブロックプログラミングを自由に自分で作れちゃうやつ

2021年のゴールデンウィークに発表があって、プラグインが色々でてきました！

公式のサンプル: https://google.github.io/blockly-samples/ 

ということで、このプラグインを使った(ギリギリ)最新の情報を記事にしていきます。

### 用語

[![Image from Gyazo](https://i.gyazo.com/9db43eee0c42240b4af53bdcda6920f1.png)](https://gyazo.com/9db43eee0c42240b4af53bdcda6920f1)

[リファレンス](https://developers.google.com/blockly/reference/overview)でトップにある単語をちょっと触った自分がまとめてみました（間違ってたらコメントお願いします汗）

- Blockly まぁ全体のこと
- Workspace ブロックを組む場所
- Toolbox ブロックがある場所
- Block ブロック自体 Workspaceに置かれているものには固有idがある 画像の場合は2つのBlockがWorkspaceに置かれている
- Field ブロック内の入力やテキストの情報
- Generator ブロック配置からコードの生成 JS以外にもPythonなども

## Blocklyを使ってJavaScript実行までの最小構成

[![Image from Gyazo](https://i.gyazo.com/54b99af3dd054c0a4114ca3b44d0ff5e.gif)](https://gyazo.com/54b99af3dd054c0a4114ca3b44d0ff5e)

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://unpkg.com/blockly/blockly.min.js"></script>

  <title>Blockly test</title>
</head>
<body>
  <!-- Toolboxのブロック -->
  <xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
    <block type="math_number">
      <field name="NUM">123</field>
    </block>
    <block type="text"></block>
    <block type="text_print"></block>
  </xml>

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

  <!-- 実行ボタン -->
  <button onclick="run()">実行</button>

  <script>
    const demoWorkspace = Blockly.inject('blocklyDiv',
      {
        media: 'https://unpkg.com/blockly/media/',
        toolbox: document.getElementById('toolbox')
      });

    function run() {
      const code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
      console.log(code);
      try {
        eval(code);
      } catch (e) {
        alert(e);
      }
    }
  </script>
</body>
</html>
```

## カスタムブロックの最小構成

ifやprintなど揃ってますが、自分でもオリジナルのブロックが作れます！

作り方は以下のサイトがけっこう詳しく書いてます

https://www.catch.jp/wiki/index.php?Blockly%2FCustomBlock

ブロック情報はだいたい別ファイルにするのが普通ですが、あえて1つのファイルで書いてみると…

[![Image from Gyazo](https://i.gyazo.com/de7a84bd512e801570ce1058c3ae5fc3.gif)](https://gyazo.com/de7a84bd512e801570ce1058c3ae5fc3)

```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://unpkg.com/blockly/blockly.min.js"></script>
  <script>
    Blockly.Blocks['custom_test'] = {
      init: function () {
        this.appendDummyInput()
          .appendField("テストの値は")
          .appendField(new Blockly.FieldNumber(0), "num")
          .appendField("です");
        this.setOutput(true, null);
        this.setColour(230);
        this.setTooltip("");
        this.setHelpUrl("");
      }
    };
    Blockly.JavaScript['custom_test'] = function (block) {
      var number_num = block.getFieldValue('num');
      var code = number_num;
      return [code, Blockly.JavaScript.ORDER_NONE];
    };
  </script>

  <title>Blockly test</title>
</head>

<body>
  <!-- Toolboxのブロック -->
  <xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
    <block type="math_number">
      <field name="NUM">123</field>
    </block>
    <block type="text"></block>
    <block type="text_print"></block>
    <block type="custom_test"></block>
  </xml>

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

  <!-- 実行ボタン -->
  <button onclick="run()">実行</button>

  <script>
    const demoWorkspace = Blockly.inject('blocklyDiv',
      {
        media: 'https://unpkg.com/blockly/media/',
        toolbox: document.getElementById('toolbox')
      });

    function run() {
      const code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
      console.log(code);
      try {
        eval(code);
      } catch (e) {
        alert(e);
      }
    }
  </script>
</body>

</html>
```

## さっそくPluginを使ってスライダー入力にしてみる

ここからは、最新情報ですね。

[プラグイン](
https://github.com/google/blockly-samples/tree/master/plugins)のところへ行き、使いたいものを選択
例えば、[@blockly/field-slider](https://github.com/google/blockly-samples/tree/master/plugins/field-slider)

それぞれの説明にはビルドするようのコードしか説明に書かれてないです

ですがいったん、npmでインストールしましょう(yarnでも可)

```
npm i @blockly/field-slider
```

そうすると、node_modulesの中にdistフォルダがあって、

[![Image from Gyazo](https://i.gyazo.com/86f53235209750ccdaa940f4c6a0757c.png)](https://gyazo.com/86f53235209750ccdaa940f4c6a0757c)

これをscriptで読み込んであげればオッケーです

[![Image from Gyazo](https://i.gyazo.com/128f0d1ac7b8cf65ed0c401c548e4333.gif)](https://gyazo.com/128f0d1ac7b8cf65ed0c401c548e4333)

```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://unpkg.com/blockly/blockly.min.js"></script>
  <script src="node_modules/@blockly/field-slider/dist/index.js"></script>
  <script>
    Blockly.Blocks['custom_test'] = {
      init: function () {
        this.appendDummyInput()
          .appendField("テストの値は")
          .appendField(new FieldSlider(1, 0, 10, 0.1), "num")
          .appendField("です");
        this.setOutput(true, null);
        this.setColour(230);
        this.setTooltip("");
        this.setHelpUrl("");
      }
    };
    Blockly.JavaScript['custom_test'] = function (block) {
      var number_num = block.getFieldValue('num');
      var code = number_num;
      return [code, Blockly.JavaScript.ORDER_NONE];
    };
  </script>

  <title>Blockly test</title>
</head>

<body>
  <!-- Toolboxのブロック -->
  <xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
    <block type="math_number">
      <field name="NUM">123</field>
    </block>
    <block type="text"></block>
    <block type="text_print"></block>
    <block type="custom_test"></block>
  </xml>

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

  <!-- 実行ボタン -->
  <button onclick="run()">実行</button>

  <script>
    const demoWorkspace = Blockly.inject('blocklyDiv',
      {
        media: 'https://unpkg.com/blockly/media/',
        toolbox: document.getElementById('toolbox')
      });

    function run() {
      const code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
      console.log(code);
      try {
        eval(code);
      } catch (e) {
        alert(e);
      }
    }
  </script>
</body>

</html>
```

カスタムブロックの部分しか変えてないです。


## まとめと所感

公式にも書いといてくれって感じでつまづきました…
distはたしかにコミットはしないだろうけど、cdnとかにあったら便利だしこれからしてくれるだろうと思ってます…

でもわかると幅が増えてぜひほかのも使ってみたくなりました！(日付入力とか絶対便利)

最小構成のコードは自分のメモとしてもいいですね〜