Có một số cách để bạn có thể tuỳ chỉnh cách hiển thị của mối kết nối, mỗi cách đều có độ khó tăng dần. Để áp dụng được tất cả các nguyên tắc đó, bạn phải tạo một trình kết xuất đồ hoạ tuỳ chỉnh.
Kích thước cơ bản
Bạn có thể tuỳ chỉnh kết nối bằng cách thay đổi chiều rộng hoặc chiều cao của kết nối trong khi vẫn giữ nguyên hình dạng cơ bản. Để thực hiện điều này, bạn cần tạo một thành phần trình cung cấp hằng số tuỳ chỉnh và ghi đè một số hằng số.
Các trình kết xuất khác nhau xác định và sử dụng hằng số khác nhau, vì vậy hãy xem tài liệu tham khảo cho lớp cấp cao của bạn:
Đối với trình kết xuất cơ sở, bạn có thể ghi đè NOTCH_WIDTH
và
NOTCH_HEIGHT
cho các kết nối tiếp theo và trước đó, đồng thời
TAB_WIDTH
và TAB_HEIGHT
đối với dữ liệu nhập và xuất
kết nối.
class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider {
constructor() {
super();
this.NOTCH_WIDTH = 20;
this.NOTCH_HEIGHT = 10;
this.TAB_HEIGHT = 8;
}
}
Hình dạng cơ bản
Bạn có thể tuỳ chỉnh mối kết nối bằng cách ghi đè hình dạng cơ bản của kết nối. Hình dạng cơ bản có chiều cao, chiều rộng và hai đường dẫn.
Mỗi đường dẫn đều vẽ một hình dạng giống nhau, nhưng có hai đầu đối diện!
Điều này là cần thiết vì khi ngăn vẽ đường viền của nó sẽ vẽ từng loại kết nối theo cả hai hướng. Ví dụ: các đường kết nối trước được vẽ từ trái sang phải, nhưng các đường nối tiếp theo là được vẽ từ phải sang trái. Vì vậy, bạn cần cung cấp đường dẫn cho cả hai những trường hợp đó.
Bạn có thể ghi đè phương thức makeNotch
cho bước tiếp theo và trước đó
và phương thức makePuzzleTab
để nhập và nhập
kết nối đầu ra.
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)]),
};
}
}
Hãy xem tài liệu về đường dẫn MDN SVG để biết thông tin về cách
để xác định chuỗi đường dẫn. Đã cung cấp không gian tên Blockly.utils.svgPaths
dưới dạng một trình bao bọc mỏng xung quanh các chuỗi này để dễ đọc hơn.
Hình dạng để kiểm tra kết nối
Bạn có thể tuỳ chỉnh kết nối bằng cách thay đổi hình dạng dựa trên kiểm tra kết nối.
Nhờ đó, bạn có thể tạo nhiều hình dạng để biểu thị các loại dữ liệu. Ví dụ: chuỗi có thể được biểu thị bằng các kết nối hình tam giác, trong khi boolean được biểu thị bằng các kết nối tròn.
Để cung cấp các hình dạng khác nhau cho nhiều cách kiểm tra kết nối, bạn cần ghi đè
phương thức shapeFor
. Bạn nên khởi tạo các hình dạng trả về
trong init
.
Xem hình dạng cơ bản để biết thông tin về các loại hình dạng được hỗ trợ.
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);
}
}
Dữ liệu đầu vào tuỳ chỉnh
Bạn có thể tuỳ chỉnh hình dạng của kết nối bằng cách tạo một dữ liệu đầu vào hoàn toàn tuỳ chỉnh. Chiến dịch này chỉ được thực hiện nếu bạn muốn một số kết nối trông khác với các kết nối khác, mà bạn không muốn dựa trên quy trình kiểm tra kết nối.
Ví dụ: nếu bạn muốn một số đầu vào giá trị được thụt lề như đầu vào câu lệnh, bạn có thể tạo dữ liệu đầu vào tuỳ chỉnh để hỗ trợ việc này.
Tạo lớp dữ liệu đầu vào tuỳ chỉnh
Làm theo các bước để tạo dữ liệu nhập tuỳ chỉnh.
Tạo một thuộc tính có thể đo lường
Bạn cần tạo một chế độ có thể đo lường để đại diện cho dữ liệu đầu vào tuỳ chỉnh.
Dữ liệu đầu vào tuỳ chỉnh có thể đo lường phải kế thừa từ
Blockly.blockRendering.InputConnection
. Dữ liệu này cũng có thể bao gồm
bất kỳ dữ liệu đo lường bổ sung nào bạn cần để vẽ hình dạng của đầu vào.
export class CustomInputMeasurable extends Blockly.blockRendering.InputConnection {
constructor(constants, input) {
super(constants, input);
// Any extra measurement data...
}
}
Tạo thực thể có thể đo lường
Thông tin kết xuất cần tạo thực thể tùy chỉnh của bạn
có thể đo lường. Để thực hiện việc này, bạn cần ghi đè phương thức 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);
}
}
Tạo hàng nếu muốn
Theo mặc định, giá trị nhập vào sẽ không tạo hàng mới. Nếu bạn muốn biết thông tin
để kích hoạt phần cuối hàng, bạn cần ghi đè
shouldStartNewRow_
phương thức của
thông tin kết xuất.
export class RenderInfo extends Blockly.blockRendering.RenderInfo {
shouldStartNewRow_(currInput, prevInput) {
if (prevInput instanceof CustomInput) return true;
return super.shouldStartNewRow_(currInput, prevInput);
}
}
Tùy chọn tạo một hình dạng cho thông tin bạn nhập
Bạn nên lưu trữ hình dạng của dữ liệu đầu vào trong một hằng số, giống như chúng tôi làm việc với các hình khía và các thẻ giải đố. Việc này giúp giữ cho mã của bạn luôn ngăn nắp và dễ dàng sửa đổi hơn sau này.
Vẽ đầu vào
Cuối cùng, bạn cần phải điều chỉnh ngăn kéo để vẽ hình dạng.
Thông tin đầu vào tuỳ chỉnh có thể:
Ảnh hưởng đến đường viền của khối, chẳng hạn như nhập câu lệnh
Hoặc tác động đến bên trong khối, chẳng hạn như mục nhập giá trị cùng dòng
Nếu dữ liệu đầu vào ảnh hưởng đến đường viền của khối, hãy ghi đè
drawOutline_
, nếu không, hãy ghi đè
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);
}
}
}
}
}