您有多種方式可以自訂連線的外觀,而且每種方法的難度都會提高。這些服務都需要建立自訂轉譯器。
基本維度
您可以調整連線的寬度或高度來自訂連線,同時保持相同的基本形狀。如要這麼做,您必須建立自訂的常數提供者元件,並覆寫某些常數。
不同的轉譯器會定義並使用不同常數,因此請參閱父類別的參考說明文件:
對於基本轉譯器,您可以覆寫下一個和上一個連線的 NOTCH_WIDTH
和 NOTCH_HEIGHT
,以及覆寫輸入和輸出連線的 TAB_WIDTH
和 TAB_HEIGHT
。
class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider {
constructor() {
super();
this.NOTCH_WIDTH = 20;
this.NOTCH_HEIGHT = 10;
this.TAB_HEIGHT = 8;
}
}
基本形狀
您可以覆寫連結的基本形狀來自訂連線。基本形狀包含高度、寬度和兩路徑。
每個路徑繪製的形狀都相同,但從相反方向繪製!
這是必要的,因為導覽匣會繪製區塊的外框,因此會雙向繪製每種連線類型。例如,先前的連線是從左到右繪製,但下一個連線會從右至左繪製。因此,您需要提供這兩種情況的路徑。
您可以覆寫下一個和上一個連線的 makeNotch
方法,以及輸入和輸出連線的 makePuzzleTab
方法。
class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider {
makePuzzleTab() {
const width = this.TAB_WIDTH;
const height = this.TAB_HEIGHT;
return {
type: this.SHAPES.PUZZLE,
width,
height,
pathUp: Blockly.utils.svgPaths.line([
Blockly.utils.svgPaths.point(-width, -height / 2),
Blockly.utils.svgPaths.point(width, -height / 2)]),
pathDown: Blockly.utils.svgPaths.line([
Blockly.utils.svgPaths.point(-width, height / 2),
Blockly.utils.svgPaths.point(width, height / 2)]),
};
}
}
如要瞭解如何定義路徑字串,請參閱 MDN SVG 路徑說明文件。提供 Blockly.utils.svgPaths
命名空間做為這些字串的細包裝函式,使名稱更容易閱讀。
連線檢查的形狀
您可以根據連線的連線檢查變更形狀來自訂連線。
這可讓您建立不同的形狀來代表不同的資料類型。例如,字串可能以三角形連線表示,而布林值則以圓形連線表示。
如要為不同的連線檢查提供不同的形狀,您必須覆寫 shapeFor
方法。傳回的形狀應在 init
中初始化。
如要瞭解支援的形狀類型,請參閱「基本形狀」。
export class ConstantProvider extends Blockly.blockRendering.BaseConstantProvider {
shapeFor(connection) {
let check = connection.getCheck();
// For connections with no check, match any child block.
if (!check && connection.targetConnection) {
check = connection.targetConnection.getCheck();
}
if (check && check.includes('String')) return this.TRIANGULAR_TAB;
if (check && check.includes('Boolean')) return this.ROUND_TAB;
return super.shapeFor(connection);
}
}
自訂輸入內容
您可以建立自訂輸入來源來自訂連線形狀。只有當您希望某些連線與其他連線不同時,您才會這麼做,但不希望其根據連線檢查加以根據。
舉例來說,如果您希望某些值輸入能以類似陳述式輸入縮排,您可以建立自訂輸入來支援此功能。
建立自訂輸入類別
按照建立自訂輸入的步驟操作。
建立可評估的指標
您必須建立可評估來代表自訂輸入內容。
可測量的自訂輸入內容應繼承自 Blockly.blockRendering.InputConnection
。也可包含繪製輸入內容形狀所需的任何額外測量資料。
export class CustomInputMeasurable extends Blockly.blockRendering.InputConnection {
constructor(constants, input) {
super(constants, input);
// Any extra measurement data...
}
}
將可評估的成效指標例項化
您的轉譯資訊需要對自訂的測量結果執行個體化。如要這麼做,您必須覆寫 addInput_
方法。
export class RenderInfo extends Blockly.blockRendering.RenderInfo {
addInput_(input, activeRow) {
if (input instanceof CustomInput) {
activeRow.elements.push(new CustomInputMeasurable(this.constants_, input));
}
super.addInput_(input, activeRow);
}
}
視需要建立資料列
根據預設,輸入內容不會建立新的資料列。如果您希望輸入內容觸發資料列結尾,就必須覆寫轉譯資訊的 shouldStartNewRow_
方法。
export class RenderInfo extends Blockly.blockRendering.RenderInfo {
shouldStartNewRow_(currInput, prevInput) {
if (prevInput instanceof CustomInput) return true;
return super.shouldStartNewRow_(currInput, prevInput);
}
}
視需要為輸入內容建立形狀
建議您以常數方式儲存輸入內容的形狀,就像儲存凹槽和益智分頁一樣。這樣做可讓程式碼保持井然有序,也可以方便日後修改。
繪製輸入
最後,您必須修改導覽匣才能繪製形狀。
自訂輸入內容可採用下列其中一種做法:
影響區塊的輪廓,例如陳述輸入內容
或是影響區塊的內部,例如內嵌值輸入內容
如果輸入內容會影響區塊的外框,請覆寫 drawOutline_
,否則覆寫 drawInternals_
。
export class Drawer extends Blockly.blockRendering.Drawer {
drawOutline_() {
this.drawTop_();
for (let r = 1; r < this.info_.rows.length - 1; r++) {
const row = this.info_.rows[r];
// Insert checks for your input here!
if (row.getLastInput() instanceof CustomInputMeasurable) {
this.drawCustomInput(row);
} else if (row.hasJaggedEdge) {
this.drawJaggedEdge_(row);
} else if (row.hasStatement) {
this.drawStatementInput_(row);
} else if (row.hasExternalInput) {
this.drawValueInput_(row);
} else {
this.drawRightSideRow_(row);
}
}
this.drawBottom_();
this.drawLeft_();
}
protected drawInternals_() {
for (const row of rows) {
for (const elem of row) {
// Insert checks for your input here!
if (elem instanceof CustomInputMeasurable) {
this.drawCustomInput(elem);
}
if (Types.isInlineInput(elem)) {
this.drawInlineInput_(elem as InlineInput);
} else if (Types.isIcon(elem) || Types.isField(elem)) {
this.layoutField_(elem as Field | Icon);
}
}
}
}
}