如何使用 Javascript 创建 Blockly 块的实例?
How can I make an instance of a block of Blockly with Javascript?
我在 customBlocks.js
文件中使用 Blockly
完成了以下块:
Blockly.Blocks['move_right'] = {
init: function() {
this.appendValueInput("PIXELS")
.setCheck("Number")
.appendField("move to right");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(290);
this.setTooltip('');
this.setHelpUrl('http://www.example.com/');
}
};
Blockly.JavaScript['move_right'] = function(block) {
var value_pixels = Blockly.JavaScript.valueToCode(block, 'PIXELS', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var codeMoveRight = "$(\"#moveDiv\").animate({\n " +
"left: \"+=" + value_pixels + "px\"\n" +
"},1000);\n";
return codeMoveRight;
};
将 div
向右移动,具体取决于您在其上设置的像素数。您必须在 move_right
块内放置一个 math_number
块,以放置您要移动的像素数量。
我的 html
文件中有一个 workspace
变量,它注入了 Blockly workspace
:
var workspace = Blockly.inject('blocklyDiv',
{toolbox: document.getElementById('toolbox')});
我想做什么
它是从 JavaScript 中检索该块在 Blockly 的工作区中显示一次时的像素数量,而不是之前。
我试过的
我直接尝试从我的兄弟(Google Chrome)的控制台访问 workspace
变量并且可以获得 "child blocks"但不是它们的价值。如下:
console.log(workspace.topBlocks_[0].childBlocks_);
我还尝试将工作区转换为 dom,然后再转换为文本:
var xml = Blockly.Xml.workspaceToDom(workspace);
var xml_text = Blockly.Xml.domToText(xml);
console.log(xml_text);
在这里我可以看到 "child Block" 的值,我的意思是 math_number
块,它存储在文本中,但我不知道如何获取它。
为什么我要实现它?
因为我想要的是检查用户是否向右移动了300像素。如果是这样,那么我将显示一条消息,其中我将 "You get it!".
我的问题
是否可以创建我放在工作区中的那个块的实例,然后使用该实例访问它的像素值?
编辑:
我也可以像@Oriol 所说的那样得到 left
值:
$('#moveDiv').css('left');
但我没有把它放在这里,因为它使用了 Jquery
的 属性(这根本不重要,因为它也是一个不错的选择,但不是预期的那样)。我的意图是在将 Block
放在 Blockly workspace
上之后获取一个实例,以便以后随时使用它进行操作。
有一种方法 setWarningText 可以显示这种警告。您可以按如下方式修改您的生成器:
Blockly.JavaScript['move_right'] = function(block) {
var value_pixels = Blockly.JavaScript.valueToCode(block, 'PIXELS', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var codeMoveRight = "$(\"#moveDiv\").animate({\n " +
"left: \"+=" + value_pixels + "px\"\n" +
"},1000);\n";
// You can show a blockly warning
if( value_pixels >= 300 ) block.setWarningText("You get it!");
// Or you can store its value elsewere...
// myExternalVar = value_pixels;
return codeMoveRight;
};
这将在块本身中显示为警告图标。
无论如何,如果你想"remember"这个value_pixels变量,我相信更简单的方法是在生成器中做,如上所示。您始终可以将其存储在可从自定义函数访问的外部变量中。
编辑:
如果出于其他目的需要遍历块结构,可以使用:
- Blockly.mainWorkspace.getTopBlocks(true); // 获取顶级块
- 对顶级阻止列表的迭代
- block = block.nextConnection && block.nextConnection.targetBlock(); // 将"descend"分成一个块的子块,然后遍历它们
- if(block.type=="move_right") ... // 检查特定的块类型
我希望这能提供一个起点,但了解这些 "tricks" 的最佳方法是阅读 Blockly 源代码。即使代码通常有很好的注释,AFAIK 也没有办法自动生成文档,而且它在网络上也不可用。
我知道这个问题有点老了,但如果您仍然想要更精细的访问,您应该使用块 IDs
(每个块都有一个唯一的 ID
)。
而且,要获取块元素,请不要忘记定义其输入和字段名称,以便您可以引用它们:
示例块:
Blockly.Blocks['my_block_unique_name'] = {
init: function() {
this.appendDummyInput("this_input_unique_name_for_this_block")
.appendField("this block do:")
.appendField(new Blockly.SomeField(...), "this_field_unique_name_for_this_block");
this.setColour(60);
this.setTooltip('this block do something');
}
//an crude example, be aware that blocks on fyout list will trigger it, if you did not use the block this block is disposed.
console.log(this.id);
};
您可以使用一个事件来获取它的 ID
,将 IDs
和一些有用的信息存储在另一个地方,等等...
因此,您可以执行以下操作:
mainworkspace = Blockly.mainWorkspace
block = mainworkspace.getBlockById(id);
input = block.getInput("imageInput");
// You can use `setField(newValue,name)` too in a more clean way.
input.removeField("FieldImageButton");
input.appendField(new Blockly.SomeField(...), "this_field_unique_name_for_this_block")
所以你可以分析方块isInFlyout
看它是否被使用(如果它是来自打开类别的方块或者从中拖出的方块,在使用中),我希望它帮助你和其他人。
我在 customBlocks.js
文件中使用 Blockly
完成了以下块:
Blockly.Blocks['move_right'] = {
init: function() {
this.appendValueInput("PIXELS")
.setCheck("Number")
.appendField("move to right");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(290);
this.setTooltip('');
this.setHelpUrl('http://www.example.com/');
}
};
Blockly.JavaScript['move_right'] = function(block) {
var value_pixels = Blockly.JavaScript.valueToCode(block, 'PIXELS', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var codeMoveRight = "$(\"#moveDiv\").animate({\n " +
"left: \"+=" + value_pixels + "px\"\n" +
"},1000);\n";
return codeMoveRight;
};
将 div
向右移动,具体取决于您在其上设置的像素数。您必须在 move_right
块内放置一个 math_number
块,以放置您要移动的像素数量。
我的 html
文件中有一个 workspace
变量,它注入了 Blockly workspace
:
var workspace = Blockly.inject('blocklyDiv',
{toolbox: document.getElementById('toolbox')});
我想做什么
它是从 JavaScript 中检索该块在 Blockly 的工作区中显示一次时的像素数量,而不是之前。
我试过的
我直接尝试从我的兄弟(Google Chrome)的控制台访问
workspace
变量并且可以获得 "child blocks"但不是它们的价值。如下:console.log(workspace.topBlocks_[0].childBlocks_);
我还尝试将工作区转换为 dom,然后再转换为文本:
var xml = Blockly.Xml.workspaceToDom(workspace); var xml_text = Blockly.Xml.domToText(xml); console.log(xml_text);
在这里我可以看到 "child Block" 的值,我的意思是
math_number
块,它存储在文本中,但我不知道如何获取它。
为什么我要实现它?
因为我想要的是检查用户是否向右移动了300像素。如果是这样,那么我将显示一条消息,其中我将 "You get it!".
我的问题
是否可以创建我放在工作区中的那个块的实例,然后使用该实例访问它的像素值?
编辑:
我也可以像@Oriol 所说的那样得到 left
值:
$('#moveDiv').css('left');
但我没有把它放在这里,因为它使用了 Jquery
的 属性(这根本不重要,因为它也是一个不错的选择,但不是预期的那样)。我的意图是在将 Block
放在 Blockly workspace
上之后获取一个实例,以便以后随时使用它进行操作。
有一种方法 setWarningText 可以显示这种警告。您可以按如下方式修改您的生成器:
Blockly.JavaScript['move_right'] = function(block) {
var value_pixels = Blockly.JavaScript.valueToCode(block, 'PIXELS', Blockly.JavaScript.ORDER_ATOMIC);
// TODO: Assemble JavaScript into code variable.
var codeMoveRight = "$(\"#moveDiv\").animate({\n " +
"left: \"+=" + value_pixels + "px\"\n" +
"},1000);\n";
// You can show a blockly warning
if( value_pixels >= 300 ) block.setWarningText("You get it!");
// Or you can store its value elsewere...
// myExternalVar = value_pixels;
return codeMoveRight;
};
这将在块本身中显示为警告图标。
无论如何,如果你想"remember"这个value_pixels变量,我相信更简单的方法是在生成器中做,如上所示。您始终可以将其存储在可从自定义函数访问的外部变量中。
编辑:
如果出于其他目的需要遍历块结构,可以使用:
- Blockly.mainWorkspace.getTopBlocks(true); // 获取顶级块
- 对顶级阻止列表的迭代
- block = block.nextConnection && block.nextConnection.targetBlock(); // 将"descend"分成一个块的子块,然后遍历它们
- if(block.type=="move_right") ... // 检查特定的块类型
我希望这能提供一个起点,但了解这些 "tricks" 的最佳方法是阅读 Blockly 源代码。即使代码通常有很好的注释,AFAIK 也没有办法自动生成文档,而且它在网络上也不可用。
我知道这个问题有点老了,但如果您仍然想要更精细的访问,您应该使用块 IDs
(每个块都有一个唯一的 ID
)。
而且,要获取块元素,请不要忘记定义其输入和字段名称,以便您可以引用它们:
示例块:
Blockly.Blocks['my_block_unique_name'] = {
init: function() {
this.appendDummyInput("this_input_unique_name_for_this_block")
.appendField("this block do:")
.appendField(new Blockly.SomeField(...), "this_field_unique_name_for_this_block");
this.setColour(60);
this.setTooltip('this block do something');
}
//an crude example, be aware that blocks on fyout list will trigger it, if you did not use the block this block is disposed.
console.log(this.id);
};
您可以使用一个事件来获取它的 ID
,将 IDs
和一些有用的信息存储在另一个地方,等等...
因此,您可以执行以下操作:
mainworkspace = Blockly.mainWorkspace
block = mainworkspace.getBlockById(id);
input = block.getInput("imageInput");
// You can use `setField(newValue,name)` too in a more clean way.
input.removeField("FieldImageButton");
input.appendField(new Blockly.SomeField(...), "this_field_unique_name_for_this_block")
所以你可以分析方块isInFlyout
看它是否被使用(如果它是来自打开类别的方块或者从中拖出的方块,在使用中),我希望它帮助你和其他人。