Blockly开发入门指北

【腾讯文档】Blockly开发入门指北
https://docs.qq.com/doc/DRWRDUU5kR2lhaGNN

  1. 写这篇文章的目的

最近公司的项目用到了Blockly这个东西(不知道怎么形容,就用东西这个词吧),但是这个东西呢,官网没有中文,示例给的也都很简单,api文档也是杂七杂八什么都有令人头秃,国内用这个的人似乎也不多(是不是真的不多我也不清楚),网络上的相关文档很少,成体系的教程也没有,因此我打算自己写一个,出于个人水平问题,如有疏漏,在所难免。

  1. 什么是Blockly

Blockly是Google开发的一套“字符串编辑器”,我个人是这样看待的,通过少儿编程的方式实现某个功能,也就是官网上给出的那个样子,用拼图一样的东西进行拼接,通过这种方式完成代码生成。对Blockly更官方的解释,请查看百度或Blockly官网。

  1. 开发思维

为什么要有开发思维这一节呢,因为会接触Blockly二次开发的同学们应该也是程序员吧,用写代码的那种逻辑性很强、严谨感很强的思维是看不懂Blockly代码的,所以专门用这一节来描述Blockly是个什么鬼,从而掌握其开发思想。

首先看一下界面的样子,如下图所示:

下面的图片是展开一个分组之后的样子,通过上面的图片,可以看到整个界面大致分为两个部分:积木选择区和工作区,工作区的右下角是功能按钮,从上到下依次为定位、放大、缩小、删除。

在操作积木时,在左侧的积木选择区选择一个积木,然后拖拽到右侧的工作区中即可,关于积木本身的特性我们稍后细说。

下面是一个拼好一个模型的图片:

这就是一个拼好的积木模型了,这个示例中包含了很多自定义的积木块。那么它生成的代码是什么样子的呢,来看下面的图片:

这就是上面模型所生成的代码了,到这里有些有想法的同学可能会问,这个代码怎么看起来四不像呢,这就是一开始我称呼它为”字符串编辑器“而不是代码编辑器的原因所在,根据官网的介绍,Blockly支持多种语言的生成,包括python,JavaScript,php等语言,但实际上,在后面的实践过程中,我越来越理解到它并不是真正的开发代码,其本质只是一堆字符串,只不过是这些字符串符合某种编程语言的规范而已,基于这个发现,你可能会觉得这很low诶,但我认为这恰恰是Blockly的高明之处,Blockly本身支持的那些语言只是预设好了一套字符串,如果你想要支持其他的语言也不是不可以,完全可以自己进行扩展,这种看起来很low的做法,恰恰造就了Blockly跨平台的特点。

好的,通过上面的图片,我们已经知道了它生成的代码,但是这些代码在页面上是不可见的,是隐藏的背后的逻辑,那么可见的积木是什么描述的呢?

在Blockly的API中,有一项Blockly.XML的内容,是的没错,我们能够看到的这些积木,是由xml来表示的,下面看一下这个xml长什么样子:

好的,看不太懂,不过这没关系,因为这个xml只是为了告诉Blockly工作区中应该渲染什么,如何渲染,在实践的过程也只是在数据库中存了一下,用于下次打开时候的回显,并不牵涉任何业务。在这个XML中,我们看到了它只规定了应该渲染什么,工作区中都有什么,但并没有规定每个积木应该长什么样子,比如它是什么颜色,文字是什么?

积木的颜色,积木上面的文字等这些信息,了解面向对象开发的同学可能比较敏感,因为它们都属于积木块自身的属性,外观属性,这些外观属性一般是静态的,当然,在文档中也要求是静态的,这是因为这些积木渲染的时机很早,在Blockly界面初始化的时候,这些外观定义就要被用到,如果存在动态的外观属性,比如通过接口获取某个下拉框的选项,那么你需要在Blockly界面初始化之前就保证数据已经准备完备,这个数据的获取时机,需要慎重考虑,要防止取不到值导致工作区加载出问题,也要规避请求时间过长阻塞Blockly界面初始化导致的白屏。

那么到现在为止,我们已经了解了构成Blockly的几大要素,首先是积木选择区,要想使用自定义的积木,我们必须将它注册到积木选择区中,否则我们是无法使用到它的;其次是工作区渲染,即上面的XML,它是对工作区需要渲染哪些组件的说明书,然后是积木的外观定义,告诉Blockly,这个积木块应该长什么样子,外观如何;最后是代码生成,将每块积木所对应的代码,按照积木拼接的规则组合在一起。

OK,现在我们已经了解了Blockly是如何工作的,由哪几部分组成,接下来就可以尝试开发自己的积木了。

  1. 开发准备

首先在项目中安装Blockly,按照官方github上的描述,执行npm install blockly命令。

安装完成后,我们就可以在要使用到的页面中引入Blockly,引入代码如下所示:

import Blockly from 'blockly';

然后我们开始初始化Blockly界面,不得不说官方文档写的真是一言难尽,我在官网的Fixed-sized Workspace这一节里才摸到门路。

首先写一个div,指定要放置界面的DOM节点,给它一个id,再赋予它宽和高,然后在js中加载Blockly,按照官网的示例代码:

Add an empty div somewhere in the page's body and set its size:

【在页面的什么地方添加一个空的div并设置尺寸】

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

Add the structure of the toolbox (see Defining the Toolbox for more information) anywhere on the page:

【在页面的任何位置添加工具栏的结构(PS:任何位置,感觉好随便)】

<xml id="toolbox" style="display: none">

<block type="controls_if"></block>

<block type="controls_repeat_ext"></block>

<block type="logic_compare"></block>

<block type="math_number"></block>

<block type="math_arithmetic"></block>

<block type="text"></block>

<block type="text_print"></block>

</xml>

好一个display:none,这个东西就是为了不让它直接展示,而是传递给Blockly使用,我当时还特地把它删了看看啥效果。

Finally, call the following to inject Blockly into an empty div. This script should be at the bottom of the page, or called by the onload event.

【最后,在空div上调用Blockly inject方法,这个脚本必须在页面底部,或者在onload事件执行】

<script>

var workspace = Blockly.inject('blocklyDiv',

{toolbox: document.getElementById('toolbox')});

</script>

到这里初始化的工作就基本上结束了,有一个注意点就是inject这个方法,来看一下api介绍:

该方法接收两个参数,第一个是必填项,指定界面的渲染元素,可以是元素,它的id,或者一个CSS选择器,参数类型可以为元素或字符串;第二个参数是可选的,接收一个选项对象。

下面是我的真实代码:

现在我们就有了一个基础的界面,在inject的时候,可以指定Blockly的一些全局配置,在官方文档中介绍的还是比较详细的:

在实际使用过程中,大部分选项都可以保持默认,如果想要一些不一样的东西,可以自行设置参数。在以上的配置项中,有一个配置项是比较重要的,就是toolbox这个配置项,该配置项接收参数类型为XML Nodes or string,Tree structure of categories and blocks available to the user. See defining the toolbox for more information.

这段描述的大意是:提供给用户的块和分类的树形结构,更多信息查看“工具栏定义”。

这表示这个配置项指定了界面左侧的积木选择区所展示的内容,点击这个链接将会跳转到Toolbox一节,在这一节中提供了两种定义的方式,分别是XML与Json,我自己使用的是XML,下面还有工具栏的一些样式配置,分类配置等,非常详细,感兴趣的话可以自行了解。

在完成以上这些工作之后,我们发现现在工具栏中的积木都是Blockly内置好的,那么接下来,我们开始正式的写一个自定义积木。

  1. 定义一个最简单的积木

通过上面的了解,我们知道要想使用一个自定义积木,必须要在工具栏中注册这个积木,注册的前提就是你必须先有一个积木(这是废话,凑字数的),

现在我们参考官网上Add Custom Blocks一节来进行定义,通览这篇文档,可以看到积木定义大概分三步,首先定义积木,提供Json和JavaScript两种方式定义,我个人使用的是后者,为了方便以后的功能开发。定义好之后进行引用,最后指定其生成的代码。

现在我们一步一步来做,首先在你喜欢的位置创建一个js文件,用于定义我们的第一个积木,根据程序员的传统美德,我把它其名为HelloWorld.js,并复制上官网的代码,不要忘记在首行添加import语句。

分析这段代码,从第二行看起,Blockly.Blocks['string_length']={...},这是一个明显的赋值语句,对Blockly.Blocks这个对象,扩展了名为string_length的属性,并对该属性赋值为一个对象,看到这里,我们联想一下之前看到过的那个看不太懂的XML描述内容,在block节点中,不是有一个type属性吗,这个type属性指定了这个块的类型,类型的名字,就是这个Blockly.Blocks中某个属性的名字,通过这个属性的名字,就可以获取到对应积木的描述信息,好的,为了避免与内置积木重名,我们来修改一下这个属性名,换一个高大上的名字。

怎么样?是不是有了高大上的感觉呢?

下面进行第二步,注册积木。

按照文档给出的示例代码,我们给它安排!

(使用模块化开发的同学不要忘记import哈)

然后是激动人心的最后一步啦,同样按照文档给出的示例代码:

看第14行,是不是很眼熟的写法,没错,就是和上面的是一个套路,扩展一个内部对象,所以后面的属性名当然也要修改成和上面一致的啦。这里有一个注意点,就是前面的JavaScript,这个不是固定的写法哦,JavaScript表示这是用于生成JavaScript代码时执行的方法,如果想要获得其他语言的代码,比如Python,那么就要把JavaScript改成Python才可以,如果对不上的话,在获取生成的代码时会出错哦。

到此为止,我们的第一个自定义积木就写好啦,是不是非常简单?现在查看一下运行的效果:

为了更有效的看清它,我们换一个喜庆的颜色:

按照api的指引,该方法也支持RGB颜色,所以修改setColour()方法里面的参数,

修改为一个你喜欢的颜色,看一下运行效果:

非常的喜庆!

  1. 分析代码

简单的积木已经有了,大体的开发流程想必也心中有数了,现在来回顾一下积木的定义:

在解读以上代码之前,首先要了解一下积木的外观是怎么来的,在文档中的Define Blocks一节中,可以看到详细的介绍。

通过右侧的索引,看到一个积木的外观大致分为Statement Connections(语句连接器)、Output(输出/返回值)、Input(输入/参数)、Fields(字段)几个基本要素,联想一下在平时我们是如何定义一个方法的,有方法名、参数列表(参数名、参数类型)、返回类型,对应到积木的外观定义,就很明显了。现在回过头看上面的积木定义代码,是不是很清楚了?

再看下面生成代码的部分,它扩展了一个函数,并返回要生成的代码,在示例代码中,首先获取了一下被输入的参数,也就是上面命名为‘VALUE’的ValueInput中得到的内容,valueToCode方法顾名思义就是将输入的值转换为代码的方法,第一个参数为积木本身,即被执行该方法的对象,第二个参数是要取值的字段名,第三个参数是执行的顺序,在多个积木并行连接的时候有用,一般默认为0就好。

在文档的介绍中,可以看到有三种获取参数的方式,分别对应获取Value、获取Field和获取语句块,在文档中有详细的介绍,不再赘述。

值得注意的是最后的return语句,return的时候分为两种情况,一种情况是返回数组,数组中第一个元素是返回的代码语句,第二个为计算顺序,一般默认为0。另一种情况是直接返回一个字符串作为代码语句,如下面的例子:

这两种情况,主要看这个积木有没有返回值,如果没有返回值,那么说明这是一个语句块,不可能作为另一个积木的参数存在,所以直接返回字符串即可,如果有返回值,那么说明这是一个值块,即有可能作为另一个积木的参数或者输入值出现,所以需要给定一个计算顺序,返回一个数组。

入门的教程到这里就结束了,在实践的过程中,还会有更加深入的使用。

Blockly开发入门指北相关推荐

  1. Python 简单入门指北(二)

    Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值.总而言之,函数和普通变量 ...

  2. 计算机学习入门指北——计科软工网络信安侧重图析、解读专业术语、岗位分类、未来规划

    申明:本博文偏技术向,主观性较强,其中部分理解必有偏差和误解,望指出改正! 计算机学习入门指北: 作为刚入学的计算机系学生,面对一片专业术语十分蒙.区块链?大数据?开源?数据库?嵌入式开发?前端后端? ...

  3. 【Linux入门指北】第一篇 初识Linux

    目录 前言 一.Linux操作系统的发展历史 1.Linux操作系统的诞生 2.Linux操作系统的发展 1.自由软件基金会(FSF) 2.GPL协议 3.GUN工程 二.Linux的不同发行版本 1 ...

  4. Python 简单入门指北(试读版)

    本文是我小专栏中 Python 简单入门指北 一文的前半部分,如果你能坚持读完并且觉得有一定收获,建议阅读原文,只需一杯咖啡钱就可以阅读更精彩的部分,也可以订阅小专栏或者加入我的知识星球,价格都是 6 ...

  5. TensorRT详细入门指北,如果你还不了解TensorRT,过来看看吧

    首发于TensorRT详细入门指北,如果你还不了解TensorRT,过来看看吧!,最新回复以及交流请看这里~ 推荐一个深蓝学院的CUDA课程,TensorRT_Tutorial的作者伟哥讲解的,质量很 ...

  6. Flutter 入门指北(Part 9)之弹窗和提示(SnackBar、BottomSheet、Dialog)

    该文已授权公众号 「码个蛋」,转载请指明出处 前面的小节把常用的一些部件都介绍了,这节介绍下 Flutter 中的一些操作提示.Flutter 中的操作提示主要有这么几种 SnackBar.Botto ...

  7. 【杭电数电实验】verilog入门指北

    verilog入门指北 前言 指北内容 面向人群 基础实验 1-15 代码参考 正文 ISE 的安装 实验的基本操作流程 可能出现的问题 创建工程闪退 希望删除某一文件,实际上并没有删除 如何编写测试 ...

  8. 萌妹子Python入门指北(二)

    原文来自 (ixindoo.com)[http://ixindoo.com/articles/662] 只写了第一篇就好久没更新了,为啥?因为妹子学编程的意愿不强了,我也不能逼迫她去学.不过后来收到部 ...

  9. Android环信3.0即时通讯云入门指北

    Android环信3.0即时通讯云入门指北 官方文档 http://docs-im.easemob.com/im/android/sdk/import 基础集成 http://docs-im.ease ...

最新文章

  1. 百度Apollo升级发布15大新品,还要化身无人车基建狂魔 | 一文看尽首届Apollo生态大会...
  2. 德语语言文学考研c1,2015-2016同济大学德语语言文学初试考研经验(下)
  3. CSS3的box-shadow属性:给指定的区域加阴影
  4. Spring集成Mybatis错误Result Maps collection already contains value for XXX
  5. MySQL字段拼接Concat
  6. ubuntu安装proxychains及自动补全
  7. linux基础知识3
  8. 计算机科学之美,计算机科学的美学探讨
  9. 虚幻引擎自带的创建插件的插件
  10. 简述php的发展和特点,有关PHP特点的详细介绍
  11. 【iOS】TouchDown、TouchDownRepeat 和 TouchCancel 的区别
  12. 第10周项目1 二叉树算法库
  13. 阅读《21天学通Java》
  14. GBase数据库产品介绍
  15. [ CSOL - CLS ] 活动网站 map area
  16. cdn网络加速原理剖析
  17. SaaSBase:最适合小团队轻量级项目管理的软件——Tower
  18. Excel高级图表实现
  19. 20220518 十堂课教会管理者打胜仗———管理者如何快速上手,带领团队打胜仗?
  20. 银行技术岗笔试计算机基础知识点,想去银行技术岗,考试都考啥?

热门文章

  1. (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  2. Launcher app数据加载流程
  3. 苹果充电器USB端的识别电阻的设置
  4. iOS截取正六边形图片
  5. [蓝桥杯 2022 省 B] 砍竹子
  6. 启用计算机时出现了,电脑开机总提示由于启动计算机时出现了页面文件配置问题怎么办?...
  7. Android 配置gradle实现VersionCode自增
  8. 阿里云视频云低代码音视频工厂正式上线,以vPaaS全新定义企业级音视频应用开发
  9. QSFP28和QSFP+光模块能兼容吗
  10. Function ‘ngram‘ is not defined