區塊定義是指區塊的外觀和行為,包括文字 選擇顏色、形狀以及連接的其他方塊
JSON 格式與 JavaScript API 的比較
Blockly 有兩種定義區塊的方法:JSON 物件和 JavaScript 函式。 JSON 格式旨在簡化本地化作業 相關程序 適合用不同字詞排序的語言建議使用 JSON 格式 定義區塊的方法
不過,JSON 格式無法直接定義進階功能,例如 以變更者或驗證工具為例這些程式碼必須以 JavaScript 編寫,一般為 extensions。
使用 Blockly 原始 JavaScript 實作的應用程式也可以寫入 直接封鎖較低層級的 Blockly API 函式呼叫定義,如 當中各種 JavaScript 範例
Blockly.defineBlocksWithJsonArray([{
"type": "string_length",
"message0": 'length of %1',
"args0": [
{
"type": "input_value",
"name": "VALUE",
"check": "String"
}
],
"output": "Number",
"colour": 160,
"tooltip": "Returns number of letters in the provided text.",
"helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
}]);
Blockly.Blocks['string_length'] = {
init: function() {
this.appendValueInput('VALUE')
.setCheck('String')
.appendField('length of');
this.setOutput(true, 'Number');
this.setColour(160);
this.setTooltip('Returns number of letters in the provided text.');
this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp');
}
};
init
函式會建立區塊形狀。在這裡
函式,關鍵字 this
即是實際建立的區塊。
這兩個範例都載入相同的「string_length」封鎖。
在網站上,系統會使用 initJson
函式載入 JSON 格式。
這也允許在 Blockly 網頁上混用這兩種格式。是
並使用 JSON 定義區塊
僅適用於 JSON 不支援的區塊定義部分
以下是主要使用 JSON 定義的區塊範例 但是使用 JavaScript API 擴充以提供動態工具提示。
var mathChangeJson = {
"message0": "change %1 by %2",
"args0": [
{"type": "field_variable", "name": "VAR", "variable": "item", "variableTypes": [""]},
{"type": "input_value", "name": "DELTA", "check": "Number"}
],
"previousStatement": null,
"nextStatement": null,
"colour": 230
};
Blockly.Blocks['math_change'] = {
init: function() {
this.jsonInit(mathChangeJson);
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function() {
return 'Add a number to variable "%1".'.replace('%1',
thisBlock.getFieldValue('VAR'));
});
}
};
色塊顏色
區塊的主要顏色是由 JSON colour
屬性定義,
block.setColour(..)
函式,
或使用主題定義區塊
。
{
// ...,
"colour": 160,
}
init: function() {
// ...
this.setColour(160);
}
請參閱區塊顏色指南 ,掌握更多詳細資訊。
陳述式連線
使用者可使用 nextStatement
和
previousStatement
個連接器。在 Blockly 的標準版面配置中,這些連線
位於頂端和底部,而區塊則垂直堆疊。
帶有前一個連接器的區塊不得含有 輸出連接器,反之亦然。「陳述式區塊」一詞 指的是沒有輸出值的區塊。陳述式區塊通常會包含 包括先前連線和另一個連線
nextStatement
和 previousStatement
連線可
typed、
但標準區塊不會採用這項功能
下一個連線
在區塊底部建立點, 。原本沒有連線卻未連線的區塊 通常代表事件,且可以設定為 帽子。
未輸入:
{
...,
"nextStatement": null,
}
類型 (很少):
{
"nextStatement": "Action",
...
}
未輸入:
this.setNextStatement(true); // false implies no next connector, the default
類型 (很少):
this.setNextStatement(true, 'Action');
上一個連線
在區塊頂端建立凹槽,以便連接成堆疊 陳述這句話。
先前的連線無法建立輸出連線。
未輸入:
{
...,
"previousStatement": null,
}
類型 (很少):
{
"previousStatement": "Action",
...
}
未輸入:
this.setPreviousStatement(true); // false implies no previous connector, the default
類型 (很少):
this.setPreviousStatement(true, 'Action');
區塊輸出
區塊可能只有一個輸出內容,以其 開頭。輸出結果會連結至值輸入內容。具有輸出內容的區塊 通常稱為值區塊
未輸入:
{
// ...,
"output": null,
}
輸入:
{
// ...,
"output": "Number",
}
未輸入:
init: function() {
// ...
this.setOutput(true);
}
輸入:
init: function() {
// ...
this.setOutput(true, 'Number');
}
具有輸出連接器的區塊也不能有先前的陳述式凹口。
封鎖輸入來源
區塊包含一或多個輸入內容,其中每個輸入內容都具有一系列 欄位,且可能在連線中。以下提供 多種內建輸入內容類型
- 值輸入:連線至 輸出連線
值區塊。
math_arithmetic
區塊 (加法、減法) 是 這裡會顯示兩個值輸入的區塊範例 - 敘述輸入資料:會連結至 陳述式區塊的連結。 when 迴圈的巢狀部分是陳述式輸入的一個範例。
- 虛擬輸入:沒有區塊連線。就像換行是全新的 區塊已設為使用外部值輸入
- 結束資料列輸入:未建立區塊連結,且一律會像 。
JSON 格式和 JavaScript API 使用的模型略有不同 輸入內容
JSON 格式的輸入和欄位
JSON 定義的模塊結構為內插式序列
訊息字串 ( message0
、message1
、...),其中每個內插符記
(%1
、%2
、...) 是欄位或輸入結尾 (也就是輸入連接器
會在相符的 JSON argsN
陣列中顯示。格式為
目的是簡化國際化程序
{
"message0": "set %1 to %2",
"args0": [
{
"type": "field_variable",
"name": "VAR",
"variable": "item",
"variableTypes": [""]
},
{
"type": "input_value",
"name": "VALUE"
}
]
}
內插符記必須與 args0
陣列完全相符:沒有重複項目、
不會遺漏任何資料符記可按任意順序顯示,因此
變更區塊版面配置。
內插符記任一側的文字為空白字元。
使用 %
字元的文字 (例如參照百分比時) 應使用
%%
的情況下,系統就不會將其解讀為內插符記。
引數和引數類型的順序會定義
封鎖。變更其中一個字串可能會完全改變區塊的版面配置。
在字詞順序不同的語言中,這一點尤其重要
而不是英文。假設在以下假設語言中,"set %1 to %2"
(如已使用)
就需要反轉,才能表示 "put %2 in %1"
。變更中
並保留其餘 JSON 內容
會產生以下區塊:
自動變更欄位的順序、建立虛擬輸入 以及從外部切換至內部輸入來源。
同時自動取代訊息中的任何換行字元 (\n
)
字串做為結尾。
{
"message0": "set %1\nto %2",
"args0": [
{
"type": "field_variable",
"name": "VAR",
"variable": "item",
"variableTypes": [""]
},
{
"type": "input_value",
"name": "VALUE"
}
]
}
ARG
每個訊息字串都會與數字相同的 args
陣列配對。適用對象
例如,message0
帶有 args0
。內插符記
(%1
、%2
、...) 參照 args
陣列的項目。每個物件都有
type
字串。其他參數會因類型而異:
每個物件也可能有 alt
欄位。如果 Blockly 並未
無法識別物件的 type
,那麼系統則會在其定位使用 alt
物件。適用對象
例如,如果在 Blockly 中加入名為 field_time
的新欄位,則會使用
這個欄位可以使用 alt
定義舊版的 field_input
備用資料
部分區塊:
{
"message0": "sound alarm at %1",
"args0": [
{
"type": "field_time",
"name": "TEMPO",
"hour": 9,
"minutes": 0,
"alt":
{
"type": "field_input",
"name": "TEMPOTEXT",
"text": "9:00"
}
}
]
}
alt
物件可能有專屬的 alt
物件,因此允許鏈結。
最後,如果 Blockly 無法在 args0
陣列中建立物件 (
嘗試任何 alt
物件),系統就會直接略過該物件。
如果
message
字串結尾為文字或欄位,但輸入中未包含這些欄位。
因此,如果區塊的最後一個輸入內容是虛擬輸入內容,就有可能省略
args
陣列,而且不需要內插至 message
。
自動加入尾隨虛擬輸入,讓翻譯人員可以
message
,無須修改 JSON 的其餘部分。請參閱
"set %1 to %2"
(無虛擬輸入內容) 和 "put %2 in %1"
(已新增虛擬輸入)
請參閱本頁前文中的說明
implicitAlign0
在極少數情況下,自動建立的結尾虛擬輸入內容需要對齊
至 "RIGHT"
或 "CENTRE"
。如未指定,則預設值為 "LEFT"
。
在以下範例中,message0
為 "send email to %1 subject %2 secure %3"
和 Blockly 會自動在第三列新增虛擬輸入。設定
implicitAlign0
設為 "RIGHT"
會強制這個列靠右對齊。這個
未明確定義的所有輸入項目都會套用對齊規則
區塊定義,包括會取代換行字元的結束列輸入內容
('\n'
)。還有已淘汰的屬性 lastDummyAlign0
行為與 implicitAlign0
相同
設計 RTL (阿拉伯文和希伯來文) 區塊時,左右移動會反轉。
因此,"RIGHT"
會將欄位靠左對齊。
message1
、args1
、implicitAlign1
有些區塊會自然區分為兩個以上的獨立部分。 請考慮這個重複區塊,其中包含兩個資料列:
如果這個區塊是以單一訊息描述,message0
屬性
應為 "repeat %1 times %2 do %3"
。對譯者來說,這個字串很尷尬
但很難解釋 %2
替代的意思。「%2
」虛擬
而且有時候可能不需要輸入某些語言此外,
想要分享第二列文字的區塊。更好的方法
代表 JSON 使用多個訊息和引數屬性:
{
"type": "controls_repeat_ext",
"message0": "repeat %1 times",
"args0": [
{"type": "input_value", "name": "TIMES", "check": "Number"}
],
"message1": "do %1",
"args1": [
{"type": "input_statement", "name": "DO"}
],
"previousStatement": null,
"nextStatement": null,
"colour": 120
}
可定義任意數量的 message
、args
和 implicitAlign
屬性
且從 0 開始,依序遞增。請注意,
Block Factory 無法將訊息分割為多個部分,
很簡單吧!
JavaScript 中的輸入和欄位
JavaScript API 為每個輸入類型提供 append
方法:
this.appendEndRowInput()
.appendField('for each')
.appendField('item')
.appendField(new Blockly.FieldVariable());
this.appendValueInput('LIST')
.setCheck('Array')
.setAlign(Blockly.inputs.Align.RIGHT)
.appendField('in list');
this.appendStatementInput('DO')
.appendField('do');
this.appendDummyInput()
.appendField('end');
每個附加方法都可接受一個 ID 字串,供程式碼產生器使用。虛擬 和結束資料列輸入內容很少需要參照,且 ID 通常位於左側 未設定。
JavaScript API 也包含用於附加作業的通用 appendInput
方法
自訂輸入內容請注意,在此情況下,ID 應該
直接傳遞至自訂輸入的建構函式。
this.appendInput(new MyCustomInput('INPUT_NAME'))
.appendField('an example label')
所有 appendInput
方法 (通用和非一般方法) 都會傳回
輸入物件,以便使用方法鏈結進一步設定這些物件。有
是三個用來設定輸入的內建方法。
setCheck
input.setCheck('Number');
這個選用函式會用於檢查連接的輸入。如果提供了 空值的引數 (預設值),然後將這個輸入內容連結到任何區塊。 詳情請參閱類型檢查。
setAlign
input.setAlign(Blockly.inputs.Align.RIGHT);
這個選用函式可用來對齊欄位 (請見下方說明)。在架構中
自我描述性值可能會做為引數傳遞至這個函式:
Blockly.inputs.Align.LEFT
、Blockly.inputs.Align.RIGHT
和
Blockly.inputs.Align.CENTER
。
設計 RTL (阿拉伯文和希伯來文) 區塊時,左右移動會反轉。
因此,Blockly.inputs.Align.RIGHT
會將欄位靠左對齊。
appendField
建立輸入內容並附加至含有 appendInput
的區塊後,
可選擇在輸入中附加任意數量的「欄位」。這些欄位
這些詞彙經常做為標籤
說明各項輸入內容的用途
input.appendField('hello');
最簡單的欄位元素是文字。封鎖規則的慣例是 小寫文字,但專有名稱除外 (例如 Google、SQL)。
輸入列可包含任意數量的欄位元素。多個appendField
呼叫可能會鏈結在一起,以便有效率地將多個欄位新增至同一個
輸入列
input.appendField('hello')
.appendField(new Blockly.FieldLabel('Neil', 'person'));
appendField('hello')
呼叫實際上是使用明確指令的捷徑
FieldLabel 建構函式:appendField(new Blockly.FieldLabel('hello'))
。
只有在指定
類別名稱,以便使用 CSS 規則設定文字樣式。
內嵌與外部
區塊輸入內容可以算繪為外部或內部。
區塊定義可指定選用的布林值,以控制輸入內容
無論是否為內嵌內容如果為 false
,則任何輸入的值皆為外部 (例如
左區塊)。如果值為 true
,則任何輸入的值都會內嵌 (例如
右區塊)。
{
// ...,
"inputsInline": true
}
init: function() {
// ...
this.setInputsInline(true);
}
如未定義,Blockly 會使用一些經驗法則來猜測
最佳。假設 Blockly 是正確的選擇,請將這個欄位保留未定義
協助翻譯不同語言的資料
支援多種模式請參閱 "set %1 to %2"
的 JSON 範例 (外部輸入內容)
"put %2 in %1"
(內嵌輸入內容)。
如果區塊可能含有少量輸入資料 (例如數字),請使用內嵌輸入內容。
如果 collapse
,使用者可以透過內容選單切換這個選項。
設定就會啟用 (如果工具箱含有類別,則預設為 true)。
欄位
欄位會定義區塊中的大部分 UI 元素。其中包括
字串標籤、圖片和輸入內容
常值資料
例如字串和數字最簡單的範例是 math_number
區塊
使用 field_input
讓使用者輸入數字。
欄位會透過 appendField.
Blockly 提供多種內建欄位,包括文字輸入、顏色挑選器 和圖片您也可以自行建立欄位。
→ 進一步瞭解內建欄位。
→ 進一步瞭解如何建立自訂欄位。
圖示
圖示會在表面為「meta」的區塊上定義 UI 元素關於 封鎖。
系統會使用 addIcon 將圖示附加到區塊中。
Blockly 提供多種內建圖示,包括註解圖示 和警告圖示您也可以建立自己的圖示。
→ 進一步瞭解如何建立自訂圖示。
工具提示
使用者將滑鼠遊標懸停在區塊上時,工具提示可提供即時說明。 如果文字過長,系統會自動換行。
{
// ...,
"tooltip": "Tooltip text."
}
init: function() {
this.setTooltip("Tooltip text.");
}
在 JavaScript API 中,您也可以將工具提示定義為函式,而非
靜態字串。這有助於提供動態協助。請參閱 math_arithmetic
:
工具提示範例,視先前提供的下拉式選單選項而定
Blockly.Blocks['math_arithmetic'] = {
init: function() {
// ...
// Assign 'this' to a variable for use in the tooltip closure below.
var thisBlock = this;
this.setTooltip(function() {
var mode = thisBlock.getFieldValue('OP');
var TOOLTIPS = {
'ADD': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD,
'MINUS': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS,
'MULTIPLY': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY,
'DIVIDE': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE,
'POWER': Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER
};
return TOOLTIPS[mode];
});
}
};
使用 JavaScript API 時,區塊可以指定函式,而非靜態
字串,傳回工具提示字串。這允許動態工具提示。
如需範例,請參閱 math_arithmetic
。
自訂
您也可以透過提供自訂顯示功能,自訂工具提示的外觀 函式。建立可接受兩個參數的函式:
- 第一個是
<div>
元素,用於算繪內容 - 第二,當滑鼠遊標移到按鈕上時 的工具提示
在函式主體中,您可以在函式主體中,
div如果要讓滑鼠遊標懸停在區塊上定義的工具提示字串,您可以
呼叫 Blockly.Tooltip.getTooltipOfObject(element);
,其中 element
是
。
最後,請註冊此函式,讓 Blockly 在適當時機呼叫此函式:
Blockly.Tooltip.setCustomTooltip(yourFnHere);
如需範例,請參閱 自訂工具提示示範。
說明網址
封鎖後可能會有相關聯的說明頁面。這可供
「封鎖網頁」使用者,請在封鎖方塊上按一下滑鼠右鍵,然後選取「說明」
我們要使用相關內容選單如果這個值是 null
,選單就會呈現灰色。
。
{
// ...,
"helpUrl": "https://en.wikipedia.org/wiki/For_loop"
}
init: function() {
// ...
this.setHelpUrl('https://en.wikipedia.org/wiki/For_loop');
}
使用 JavaScript API 時,區塊可以指定函式,而非靜態 字串,因此會傳回網址字串,因此可提供動態說明。
變更事件監聽器和驗證工具
區塊可包含變更接聽程式函式時,可呼叫這些函式, 工作區 (包括與區塊無關的條件)這類 API 主要用於 設定封鎖文字,或設定封鎖外的類似使用者通知 工作區
這個函式是透過函式呼叫 setOnChange 的新增作業 初始化期間,如果想使用 JSON 擴充功能 在所有平台上
{
// ...,
"extensions":["warning_on_change"],
}
Blockly.Extensions.register('warning_on_change', function() {
// Example validation upon block change:
this.setOnChange(function(changeEvent) {
if (this.getInput('NUM').connection.targetBlock()) {
this.setWarningText(null);
} else {
this.setWarningText('Must have an input block.');
}
});
});
Blockly.Blocks['block_type'] = {
init: function() {
// Example validation upon block change:
this.setOnChange(function(changeEvent) {
if (this.getInput('NUM').connection.targetBlock()) {
this.setWarningText(null);
} else {
this.setWarningText('Must have an input block.');
}
});
}
}
系統會呼叫函式並傳入
變更事件。
在函式中,this
是指區塊例項。
由於函式會在任何變更時呼叫,因此如有變更,開發人員必須確保 監聽器會快速執行同時留意工作區的變更 可能會串聯或循環回事件監聽器
請參閱《controls_flow_statements
》、《logic_compare
》和《procedures_ifreturn
》
區塊範例
請注意,可編輯的欄位各有用於輸入驗證的事件監聽器 並引發副作用
變動者
變動器允許進階模塊變更形狀,最值得注意的是
使用者開啟對話方塊以新增、移除或重新排列元件。變動器可以是
使用 mutator
鍵透過 JSON 新增。
{
// ...,
"mutator":"if_else_mutator"
}
個別區塊設定
區塊執行個體有許多屬性,可設定其運作方式 使用者。您可以根據這些資料限制工作區, 網域的屬性 (例如只有一個「開始」事件),或焦點 使用者的努力 (例如教學課程)。
可刪除狀態
block.setDeletable(false);
如果設為 False,使用者就無法刪除封鎖條件。封鎖預設值 可刪除成可編輯的工作區
任何區塊 (包括復原的區塊) 都可以程式設計方式刪除:
block.dispose();
可編輯狀態
block.setEditable(false);
如果設為 False,使用者將無法變更區塊的欄位 (例如下拉式選單和文字輸入)。封鎖預設為可編輯的編輯 工作區
可移動狀態
block.setMovable(false);
如果設為 False,使用者將無法直接移動區塊。一個 如果是其他區塊的子項,即不可移除的區塊,系統可能無法與 這個區塊會隨著父項移動而移動阻攻次數 預設為可移動的工作區。
只要區塊位於 工作區
block.moveBy(dx, dy)
工作區區塊的起始位置預設為 (0, 0)。
封鎖資料
this.data = '16dcb3a4-bd39-11e4-8dfc-aa07a5b093db';
資料是附加至區塊的選用字串。當 資料字串序列化,會以該字串序列化。包括 區塊相同或複製/貼上
通常用於將區塊與外部資源建立關聯。
序列化到 JSON 時,資料會在區塊中儲存為頂層屬性:
{
"type": "my_block",
"data": "16dcb3a4-bd39-11e4-8dfc-aa07a5b093db",
// etc..
}
將資料字串序列化為 XML (舊冰箱序列化系統) 時,資料字串
會儲存在區塊中的 <data></data>
標記中:
<block type="my_block">
<data>16dcb3a4-bd39-11e4-8dfc-aa07a5b093db</data>
<!-- etc... -->
</block>
破壞
區塊具有 destroy
掛鉤,從
工作區這可用來刪除所有備份資料模型/外部
與不再需要的區塊相關聯的資源
{
// ...,
"extensions":["destroy"],
}
Blockly.Extensions.registerMixin('destroy', {
destroy: function() {
this.myResource.dispose();
}
});
Blockly.Blocks['block_type'] = {
destroy: function() {
this.myResource.dispose();
}
}
釋放區塊的父項之後,會呼叫 destroy
方法,但
以免任何子項或欄位遭到棄置。
內容選單
根據預設,封鎖功能會在右鍵顯示內容選單,讓使用者執行操作 例如新增註解或重複區塊
如要停用個別區塊的內容選單,請按照下列步驟操作:
block.contextMenu = false;
您也可以自訂選單中顯示的選項。如要自訂
請參閱
內容選單說明文件。
如要自訂個別區塊的選單,可以
customContextMenu
。這個函式採用一系列選單選項
現有的變更,也就是說,您可以同時新增及移除項目。
每個選單選項都是一個物件,其中包含三個屬性:
text
是顯示文字。enabled
為布林值。如果停用這個選項,這個選項仍會顯示,但以灰色顯示 文字。callback
是點選選項時要呼叫的函式。