연결 형태

연결 모양을 사용자 지정할 수 있는 몇 가지 방법이 있으며 각각 점점 더 어려워지고 있습니다. 이 모든 도구를 사용하려면 커스텀 렌더기를 사용하면 됩니다.

기본 측정기준

차원이 다른 여러 개의

너비 또는 높이를 변경하여 연결을 맞춤설정할 수 있지만 동일한 기본 모양을 유지할 수 있습니다. 이렇게 하려면 맞춤 상수 제공자 구성요소를 만들고 일부 상수를 재정의합니다.

렌더러마다 다른 상수를 정의하고 사용하므로 슈퍼클래스의 참조 문서를 확인하세요.

를 통해 개인정보처리방침을 정의할 수 있습니다.

기본 렌더기의 경우 NOTCH_WIDTH 및 다음 연결 및 이전 연결을 위한 NOTCH_HEIGHT 입력 및 출력용 TAB_WIDTHTAB_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);
        }
      }
    }
  }
}