Há várias maneiras de personalizar a aparência das conexões, cada uma com dificuldade crescente. Todos eles exigem a criação de um renderizador personalizado.
Dimensões básicas
Você pode personalizar as conexões alterando a largura ou a altura delas mantendo a mesma forma básica. Para fazer isso, você precisa criar um componente personalizado de provedor de constantes e modificar algumas constantes.
Diferentes renderizadores definem e usam constantes diferentes, portanto, confira a documentação de referência para sua superclasse:
.Para o renderizador base, você pode substituir NOTCH_WIDTH
e
NOTCH_HEIGHT
para as conexões anteriores e a próxima e
TAB_WIDTH
e TAB_HEIGHT
para entrada e saída
conexões de rede.
class CustomConstantProvider extends Blockly.blockRendering.ConstantProvider {
constructor() {
super();
this.NOTCH_WIDTH = 20;
this.NOTCH_HEIGHT = 10;
this.TAB_HEIGHT = 8;
}
}
Formas básicas
É possível personalizar as conexões substituindo a forma básica delas. Formas básicas ter uma altura, uma largura e dois caminhos.
Cada caminho desenha a mesma forma, mas em extremidades opostas.
Isso é necessário porque, como a gaveta desenha o contorno da de um bloco, ela desenha cada tipo de conexão em ambas as direções. Por exemplo: As conexões anteriores são desenhadas da esquerda para a direita, mas as próximas conexões são desenhada da direita para a esquerda. Portanto, você precisa fornecer caminhos para nesses casos.
Você pode substituir o método makeNotch
para o próximo e o anterior
e o método makePuzzleTab
para entrada e saída
conexões de saída.
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)]),
};
}
}
Confira a documentação do caminho do MDN SVG para informações sobre como
para definir strings de caminho. O namespace Blockly.utils.svgPaths
é fornecido
como um wrapper fino em torno dessas strings para torná-las mais legíveis.
Formas para verificações de conexão
Você pode personalizar as conexões alterando a forma com base no verificação de conexão.
Isso permite criar diferentes formas para representar diferentes tipos de dados. Por exemplo, strings podem ser representadas por conexões triangulares, enquanto booleanos são representados por conexões redondas.
Para fornecer formas diferentes para verificações de conexão diferentes, é necessário substituir
o método shapeFor
. As formas retornadas devem ser inicializadas
em init
.
Consulte formas básicas para mais informações sobre os tipos de formas são suportados.
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);
}
}
Entradas personalizadas
Você pode personalizar as formas de conexão criando uma entrada totalmente personalizada. Isso só é feita se você quiser que algumas conexões pareçam diferentes de outras, mas se não quiser que ela seja baseada na verificação de conexão.
Por exemplo, se você quiser que algumas entradas de valor sejam recuadas, como entradas de instrução, crie uma entrada personalizada para que isso aconteça.
Criar uma classe de entrada personalizada
Siga as etapas para criar uma entrada personalizada.
Crie uma métrica
Você precisa criar um elemento mensurável para representar sua entrada personalizada.
A entrada personalizada mensurável deve herdar de
Blockly.blockRendering.InputConnection
Também pode incluir
os dados de medição extras necessários para desenhar a forma da entrada.
export class CustomInputMeasurable extends Blockly.blockRendering.InputConnection {
constructor(constants, input) {
super(constants, input);
// Any extra measurement data...
}
}
Instancie seu conteúdo mensurável
Suas informações de renderização precisam instanciar sua personalização
e mensuráveis. Para fazer isso, substitua o método 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);
}
}
Como opção, crie uma linha
Por padrão, as entradas não criam novas linhas. Se você quiser que sua entrada
para acionar o fim de uma linha, você precisa substituir o
método shouldStartNewRow_
da sua
renderizar informações.
export class RenderInfo extends Blockly.blockRendering.RenderInfo {
shouldStartNewRow_(currInput, prevInput) {
if (prevInput instanceof CustomInput) return true;
return super.shouldStartNewRow_(currInput, prevInput);
}
}
Como opção, crie uma forma para a entrada
É uma boa ideia armazenar a forma de sua entrada em uma constante, assim como para entalhes e abas de quebra-cabeças. Isso mantém seu código organizado e facilita mais fácil de modificar posteriormente.
Desenhar a entrada
Por fim, você precisa modificar a gaveta para desenhar a forma.
As entradas personalizadas podem:
Afetam o contorno do bloco, como entradas de instrução
Ou afetam os componentes internos do seu bloco, como entradas de valor inline
Se a entrada afetar o contorno do bloco, substitua
drawOutline_
; caso contrário, substitua
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);
}
}
}
}
}