Blockly 可视化编程编辑器入门教程:搭积木生成代码,10 分钟从 0 到跑通

Blockly 可视化编程编辑器入门教程:搭积木生成代码,10 分钟从 0 到跑通

【免费下载链接】blockly The web-based visual programming editor. 【免费下载链接】blockly 项目地址: https://gitcode.com/gh_mirrors/bloc/blockly

Blockly 是一个基于 Web 的可视化编程编辑器,它把变量、循环、判断这些编程概念做成能拖拽拼接的积木,再把拼好的积木直接翻译成 JavaScript、Python、PHP、Lua、Dart 等语言的可运行代码。想给学生做编程练习、给产品加一个"零门槛写逻辑"的界面,用它最省事。

先跑起来:一个能拖积木的编辑器

这节只干一件事:让你尽快看到"拖积木"的效果。先准备一个 index.html,内容就是下面这些:

<!DOCTYPE html>
<html>
<body style="margin:0">
  <div id="blocklyDiv" style="width:800px;height:500px"></div>

  <xml id="toolbox" style="display:none">
    <block type="text_print"></block>
    <block type="controls_repeat_ext">
      <value name="TIMES"><shadow type="math_number"><field name="NUM">3</field></shadow></value>
    </block>
    <block type="logic_compare"></block>
  </xml>

  <script type="module">
    import * as Blockly from 'blockly';

    // 把编辑器注入到指定 div,工具栏来自隐藏的 toolbox
    const workspace = Blockly.inject('blocklyDiv', {
      toolbox: document.getElementById('toolbox'),
    });
  </script>
</body>
</html>

浏览器打开后,#blocklyDiv 里就是一个可以缩放、滚动、拖拽的积木工作区。Blockly.inject() 是唯一入口:传一个容器,再传工具栏,其余全由库接管。

有两点要交代清楚:

  1. 如果你的项目用 webpack、Vite 等打包工具,import * as Blockly from 'blockly' 直接生效;
  2. 如果想在浏览器里直接跑上面的 demo,需要先装包,把 dist/ 里的编译产物引进页面(见下面源码方式),效果一样。

从源码编译出 dist 产物

git clone https://gitcode.com/gh_mirrors/bloc/blockly
cd blockly
npm install
npm run build   # 产物落在 dist/ 下

装好后在 index.html 里按顺序引入三个文件,页面即可运行:

<script src="dist/blockly_compressed.js"></script>
<script src="dist/blocks_compressed.js"></script>
<script src="dist/javascript_compressed.js"></script>

blockly_compressed.js 是编辑器内核,blocks_compressed.js 是内置积木,javascript_compressed.js 是 JavaScript 代码生成器——三者分工在后面讲。仓库自带的完整示例在 demos/code/index.html,它额外把五种语言的生成结果并排展示,想抄一个现成的就抄它。

项目拆解:仓库由哪几部分组成

这节帮你建立一张仓库地图,后面读源码、查文档都能直接定位。

  • core/:编辑器主体。core/inject.ts 处理注入逻辑,core/workspace.ts 管理工作区(积木的集合、坐标、选择),core/block.ts 与 core/block_svg.ts 分别定义积木本身和它的屏幕渲染。
  • blocks/:内置积木的 TypeScript 定义,按功能分文件:logic.ts(逻辑)、loops.ts(循环)、math.ts(数学)、lists.ts(列表)、procedures.ts(函数)等。
  • generators/:代码生成器。每种语言一个文件夹加一个入口文件,入口把该语言下所有积木的生成函数组装成一个实例,比如 generators/javascript.ts 导出 javascriptGenerator。
  • demos/:可运行的成品示例——demos/code/(代码生成)、demos/blockfactory/(积木工厂)、demos/minimap/(小地图)、demos/storage/(云存储)。
  • tests/mocha/:单元测试,是查 API 用法最快的地方,每个核心模块都有对应测试。
  • msg/:100 多种语言的文本包(工具箱分类名、积木提示文案),改界面语言看这里。

场景实战

把积木编译成能跑的代码

最高频的需求:用户拖完积木,你要拿到真实代码。生成器干的事很直白——遍历工作区里的每块积木,调用它对应的生成函数,再拼成完整程序:

import {javascriptGenerator} from 'blockly/javascript';

const code = javascriptGenerator.workspaceToCode(workspace);
console.log(code);

想"边拖边刷新",就监听积木变化事件(Blockly.Events.BLOCK_CHANGE 对应所有会改变工作区的操作):

workspace.addChangeListener((event) => {
  if (event.type === Blockly.Events.BLOCK_CHANGE) {
    console.log(javascriptGenerator.workspaceToCode(workspace));
  }
});

效果:积木区里每搭一步,控制台就同步输出对应的 JavaScript。事件类型全表在 core/events/,想监听"拖拽""选中"等更细的操作,那里都有。

三步注册一块自定义积木

这节讲"我的业务需要一块官方没有的积木"怎么做。分三步:定义积木长相 → 写生成函数 → 验证。

第一步,注册积木定义,声明它的文案、参数和连接方式:

Blockly.defineBlocksWithJsonArray([
  {
    type: 'say_hello',
    message0: '向 %1 问好',
    args0: [{type: 'field_input', name: 'WHO', text: '世界'}],
    previousStatement: null, // 允许上下拼接
    nextStatement: null,
    colour: 160,
  },
]);

第二步,给它写生成函数,告诉生成器"这块积木翻译成什么代码":

javascriptGenerator.forBlock['say_hello'] = function(block) {
  const who = javascriptGenerator.valueToCode(block, 'WHO') || "''";
  return `console.log('Hello, ${who}');\n`;
};

第三步,把 say_hello 写进工具箱 XML,拖进工作区、运行生成,看到输出即成功。

一个提醒:积木定义和生成函数是两回事,只注册积木不写生成函数,拖是能拖,生成代码时会提示缺失;反之亦然。官方积木的写法可以直接抄 blocks/logic.ts,它展示了语句块、值块、下拉菜单的完整参数。

保存和恢复整个工作区

用户关掉页面再打开,积木还在——这靠序列化。推荐用 JSON(比 XML 更适合程序处理):

// 存成 JSON 对象,塞进 localStorage 或发给你的后端
const data = Blockly.serialization.workspaces.save(workspace);
localStorage.setItem('blocks', JSON.stringify(data));

// 下次打开时读回来
const saved = JSON.parse(localStorage.getItem('blocks'));
Blockly.serialization.workspaces.load(saved, workspace);

序列化会连同变量、自定义函数、工作区注释一起存,恢复后布局不变。仓库里的 demos/storage/ 是完整实现:它把保存/加载接到了一个带用户体系的云存储后端上,想做"多用户各自保存"可以直接参考它的 appengine/ 后端代码。

避坑指南

现象:工具箱里有分类,点进去却是空的。 原因:积木定义没注册成功,或工具箱 XML 里 type 写错了——两者必须一字不差。工具箱只是"目录",真正能被拖出来的是已注册的积木。 对策:看浏览器控制台的报错;先塞一个 text_print 这类内置积木验证链路,再逐个排查自定义类型名。

现象:workspaceToCode() 返回空字符串,或提示某积木没有生成函数。 原因:积木库和生成器是两个独立的产物,blocks_compressed.js 只负责"能拖",代码要靠 javascript_compressed.js(或 npm 里的 blockly/javascript)翻译。只引了前者,生成自然是空的。 对策:检查引入是否成对出现;自定义积木则确认每种目标语言都配了 forBlock 函数。

现象:注入成功,但编辑器高度是 0 或显示错位。 原因:Blockly.inject() 依赖容器自身的宽高来渲染,#blocklyDiv 没设明确高度就会塌掉。 对策:给容器写死宽高,或设 height: 100% 并确保父容器有高度;窗口缩放后调用 workspace.resize() 重新测量。

延伸路径

从"能拖积木"到"能出代码",你只需要记住两件事:Blockly.inject() 负责把编辑器摆上屏,generator.workspaceToCode() 负责把积木变成真代码,中间的一切——自定义积木、主题、事件、保存恢复——都是围绕这两端的扩展。

继续深入看这三处:tests/playground.html 是仓库自带的调试台,可以现场改积木、看 XML/JSON;tests/mocha/ 里每个核心模块都有测试,是查 API 标准用法的捷径;想换配色和字体,从 core/theme/ 下手,内置主题的完整写法见 core/theme/classic.ts。

【免费下载链接】blockly The web-based visual programming editor. 【免费下载链接】blockly 项目地址: https://gitcode.com/gh_mirrors/bloc/blockly

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值