Hình dạng kết nối

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

kết nối với các phương diện khác nhau

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_WIDTHNOTCH_HEIGHT cho các kết nối tiếp theo và trước đó, đồng thời TAB_WIDTHTAB_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

kết nối có hình dạng khác nhau

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!

một vết khía được vẽ từ cả hai hướng

Đ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 đó.

hướng vẽ của một khối

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

các kết nối khác nhau có hình dạng khác nhau

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

    hình ảnh nhập vào dàn ý

  • 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

    hình ảnh đầu vào nội bộ

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);
        }
      }
    }
  }
}