(1)概述:
- Blockly是一种可视化编程工具,是众多可视化编程工具的鼻祖。
- 2012年6月,Google发布的完全可视化的编程语言Goole Blockly。
- Blockly代码块由类似于积木的图形对象构成,只需要拖拖拽拽就可以实现程序的功能。
(2)详述:
- 一种基于网页的可视化是程序:
- Google Blockly是基于网页的可视化编程库,用户可以离线或者在线进行编程操作。
- 多种开发语言环境库:
- Blockly代码块可以通过自带的语言转换工具箱转换成JavaScript、Python、PHP、Lua、Dart等多种语言。
- 开源的自定义编程环境:
- 用户可以自己定义Blockly代码块放入Blockly的工具箱中,用于以后使用。
(3)Blockly的使用流程图:
- 我们可以使用Blockly的工具箱编写Blockly代码块实现程序功能,然后使用语言转换器转换为需要的语言。
- 我们也可以自定义Blockly代码块生成工具放入工具箱和语言转换器中,用于以后使用。
二.Blockly的编程环境
(1)Blockly有在线和离线版本
- 在线版本网址: https://developers.google.cn/blockly
- 离线版本下载网址:https://github.com/google/blockly
- 下载后在demos目录下,使用浏览器打开index.html即可。
(2)Blockly在线版本
(3)Blockly离线版本
-
离线Blockly的一些demo例子:
- Fixed Blockly :固定大小的Blockly块的工作空间,不会随浏览器大小变化而变化。
- Resizable Blockly :可变大小的Blockly块的工作空间,会随浏览器大小变化而变化。
- Defining the Toolbox :Blockly自定义的工具箱
- Maximum Block Limit :限制Blockly块的个数,不能超过指定Blockly个数。
- Generate JavaScript :生成JavaScript代码
- Headless :将xml代码生成其他的语言的代码
- JS Interpreter :展示使用Blockly代码块生成JavaScript代码并可以单步执行。
- Graph :通过数学公式在坐标系中生成图形
- RTL :从右到左显示Blockly块(对于阿拉伯语和希伯来语使用)
- Custom Dialogs :自定义实现覆盖浏览器对话框
- Custom Fields :自定义字段
- Cloud Storage :云存储在App Engine
- Mirrored Blockly :展示两个同步的Blockly工作区,左侧主工作区变化,右侧从工作区也发生变化。
- Accessible Blockly : 屏幕阅读无障碍访问版本
- Plane :支持35种语言
- Code Editor :将Blocky程序导出成JavaScript,Python,PHP,Lua,Dart或XML
- Blockly Developer Tools :使用Blockly构建自定义的代码块并设置到工作箱。
三.Blockly的功能模块
工具箱中有8个主要模块: blockly-master>demos>code>index.html 中可以查看源码
运行index.html结果:(右上角可以修改语言类型为简体中文)
主要为大家讲解三个文件 blockly_compressed.js , blocks_compressed.js , javascript_compressed.js
(1) blocks_compressed.js :定义了Blockly工具箱中的所有可用Blockly块,仅仅是Blockly.Blocks的内容。
以下:讲解loops(循环)模块程序代码
- 其中 Blockly.defineBlocksWithJsonArray([{...},{...},{...},...]) :用于定义某一个工具,例如循环工具所有Blockly块。
- 每一个 {...} 都包含一个循环模块的Blockly块:6个循环模块
- controls_repeat_ext
- controls_repeat
- controls_whileUntil
- controls_for
- controls_forEach
- controls_flow_statements
1 Blockly.Blocks.loops = {}; 2 Blockly.Constants.Loops = {}; 3 Blockly.Constants.Loops.HUE = 120; 4 Blockly.defineBlocksWithJsonArray([{ 5 type: "controls_repeat_ext", 6 message0: "%{BKY_CONTROLS_REPEAT_TITLE}", 7 args0: [{ 8 type: "input_value", 9 name: "TIMES", 10 check: "Number" 11 }], 12 message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1", 13 args1: [{ 14 type: "input_statement", 15 name: "DO" 16 }], 17 previousStatement: null, 18 nextStatement: null, 19 style: "loop_blocks", 20 tooltip: "%{BKY_CONTROLS_REPEAT_TOOLTIP}", 21 helpUrl: "%{BKY_CONTROLS_REPEAT_HELPURL}" 22 }, { 23 type: "controls_repeat", 24 message0: "%{BKY_CONTROLS_REPEAT_TITLE}", 25 args0: [{ 26 type: "field_number", 27 name: "TIMES", 28 value: 10, 29 min: 0, 30 precision: 1 31 }], 32 message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1", 33 args1: [{ 34 type: "input_statement", 35 name: "DO" 36 }], 37 previousStatement: null, 38 nextStatement: null, 39 style: "loop_blocks", 40 tooltip: "%{BKY_CONTROLS_REPEAT_TOOLTIP}", 41 helpUrl: "%{BKY_CONTROLS_REPEAT_HELPURL}" 42 }, { 43 type: "controls_whileUntil", 44 message0: "%1 %2", 45 args0: [{ 46 type: "field_dropdown", 47 name: "MODE", 48 options: [ 49 ["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}", "WHILE"], 50 ["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}", "UNTIL"] 51 ] 52 }, { 53 type: "input_value", 54 name: "BOOL", 55 check: "Boolean" 56 }], 57 message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1", 58 args1: [{ 59 type: "input_statement", 60 name: "DO" 61 }], 62 previousStatement: null, 63 nextStatement: null, 64 style: "loop_blocks", 65 helpUrl: "%{BKY_CONTROLS_WHILEUNTIL_HELPURL}", 66 extensions: ["controls_whileUntil_tooltip"] 67 }, { 68 type: "controls_for", 69 message0: "%{BKY_CONTROLS_FOR_TITLE}", 70 args0: [{ 71 type: "field_variable", 72 name: "VAR", 73 variable: null 74 }, { 75 type: "input_value", 76 name: "FROM", 77 check: "Number", 78 align: "RIGHT" 79 }, { 80 type: "input_value", 81 name: "TO", 82 check: "Number", 83 align: "RIGHT" 84 }, { 85 type: "input_value", 86 name: "BY", 87 check: "Number", 88 align: "RIGHT" 89 }], 90 message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1", 91 args1: [{ 92 type: "input_statement", 93 name: "DO" 94 }], 95 inputsInline: !0, 96 previousStatement: null, 97 nextStatement: null, 98 style: "loop_blocks", 99 helpUrl: "%{BKY_CONTROLS_FOR_HELPURL}", 100 extensions: ["contextMenu_newGetVariableBlock", "controls_for_tooltip"] 101 }, { 102 type: "controls_forEach", 103 message0: "%{BKY_CONTROLS_FOREACH_TITLE}", 104 args0: [{ 105 type: "field_variable", 106 name: "VAR", 107 variable: null 108 }, { 109 type: "input_value", 110 name: "LIST", 111 check: "Array" 112 }], 113 message1: "%{BKY_CONTROLS_REPEAT_INPUT_DO} %1", 114 args1: [{ 115 type: "input_statement", 116 name: "DO" 117 }], 118 previousStatement: null, 119 nextStatement: null, 120 style: "loop_blocks", 121 helpUrl: "%{BKY_CONTROLS_FOREACH_HELPURL}", 122 extensions: ["contextMenu_newGetVariableBlock", "controls_forEach_tooltip"] 123 }, { 124 type: "controls_flow_statements", 125 message0: "%1", 126 args0: [{ 127 type: "field_dropdown", 128 name: "FLOW", 129 options: [ 130 ["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}", "BREAK"], 131 ["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}", "CONTINUE"] 132 ] 133 }], 134 previousStatement: null, 135 style: "loop_blocks", 136 helpUrl: "%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}", 137 extensions: ["controls_flow_tooltip", "controls_flow_in_loop_check"] 138 }]); 139 Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS = { 140 WHILE: "%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}", 141 UNTIL: "%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}" 142 }; 143 Blockly.Extensions.register("controls_whileUntil_tooltip", Blockly.Extensions.buildTooltipForDropdown("MODE", Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS)); 144 Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS = { 145 BREAK: "%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}", 146 CONTINUE: "%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}" 147 }; 148 Blockly.Extensions.register("controls_flow_tooltip", Blockly.Extensions.buildTooltipForDropdown("FLOW", Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS)); 149 Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = { 150 customContextMenu: function (a) { 151 if (!this.isInFlyout) { 152 var b = this.getField("VAR").getVariable(), 153 c = b.name; 154 if (!this.isCollapsed() && null != c) { 155 var d = { 156 enabled: !0 157 }; 158 d.text = Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1", c); 159 b = Blockly.Variables.generateVariableFieldDom(b); 160 c = Blockly.utils.xml.createElement("block"); 161 c.setAttribute("type", "variables_get"); 162 c.appendChild(b); 163 d.callback = Blockly.ContextMenu.callbackFactory(this, c); 164 a.push(d) 165 } 166 } 167 } 168 }; 169 Blockly.Extensions.registerMixin("contextMenu_newGetVariableBlock", Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN); 170 Blockly.Extensions.register("controls_for_tooltip", Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOR_TOOLTIP}", "VAR")); 171 Blockly.Extensions.register("controls_forEach_tooltip", Blockly.Extensions.buildTooltipWithFieldText("%{BKY_CONTROLS_FOREACH_TOOLTIP}", "VAR")); 172 Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN = { 173 LOOP_TYPES: ["controls_repeat", "controls_repeat_ext", "controls_forEach", "controls_for", "controls_whileUntil"], 174 suppressPrefixSuffix: !0, 175 getSurroundLoop: function (a) { 176 do { 177 if (-1 != Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.LOOP_TYPES.indexOf(a.type)) return a; 178 a = a.getSurroundParent() 179 } while (a); 180 return null 181 }, 182 onchange: function (a) { 183 this.workspace.isDragging && !this.workspace.isDragging() && (Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN.getSurroundLoop(this) ? 184 (this.setWarningText(null), this.isInFlyout || this.setEnabled(!0)) : (this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING), this.isInFlyout || this.getInheritedDisabled() || this.setEnabled(!1))) 185 } 186 }; 187 Blockly.Extensions.registerMixin("controls_flow_in_loop_check", Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);