Arrastar

Um arrastador é um objeto de controle que coordena o arrasto de elementos arrastáveis em resposta às interações do usuário.

Existem poucas circunstâncias em que é recomendado implementar um arrastador personalizado, porque não há muito que você queira personalizar sobre como coordenar uma ação de arrastar. O plug-in de opções de rolagem implementa um arrastar personalizado porque quer adicionar rolagem à borda do espaço de trabalho, o que muda a forma como as coordenadas de pixel são convertidas em coordenadas do espaço de trabalho.

Responsabilidades

Ele tem várias responsabilidades ao executar ações de arrastar:

  • Chamar métodos de arrasto no elemento arrastável.
  • Cálculo da posição para a qual o elemento arrastável precisa se mover nas coordenadas do espaço de trabalho.
  • Chamar métodos de destino de arrasto em qualquer destino de arrasto com o cursor.

Implementação

Para criar uma barra de arrastar personalizada, você precisa implementar a interface IDragger.

class MyDragger implements IDragger {
 
// Takes in the draggable being dragged and the workspace the drag
 
// is occurring in.
  constructor
(draggable, workspace);
}

Também é possível criar uma subclasse do Blockly.dragging.Dragger integrado, que já lida com as responsabilidades básicas.

Iniciar arraste

O método onDragStart inicializa uma ação de arrastar. Ele precisa armazenar todos os dados necessários para executar o arrasto. Ele também precisa chamar startDrag no elemento arrastável que está sendo arrastado.

onDragStart(e) {
 
this.startLoc = this.draggable.getRelativeToSurfaceXY();

 
this.draggable.startDrag(e);
}

Arrasto

O método onDrag executa um arrasto. A nova posição do espaço de trabalho para o elemento arrastável precisa ser calculada com base no totalDelta, que é fornecido nas coordenadas de pixel.

Ele também precisa atualizar todos os destinos de arrasto que estão sendo apontados.

  • O wouldDelete sempre precisa ser chamado antes de outros ganchos no destino de arrasto.
  • O onDragExit sempre precisa ser chamado no alvo de arrasto antigo antes de chamar onDragEnter no novo alvo de arrasto.
  • O onDragOver precisa ser chamado após onDragEnter na primeira vez que o alvo de arrasto é destacado e em cada chamada adicional para onDrag em que o alvo de arrasto ainda está destacado.
onDrag(e, totalDelta) {
 
// Update the draggable location.
 
const delta = this.pixelsToWorkspaceUnits(totalDelta);
 
const newLoc = Coordinate.sum(this.startLoc, delta);
 
this.draggable.drag(newLoc, e);

 
// Call wouldDeleteDraggable.
 
if (isDeletable(this.draggable)) {
   
this.draggable.setDeleteStyle(
     
// Checks that the drag target is an `IDeleteArea` and calls `wouldDelete`
     
// on it.
     
this.wouldDeleteDraggable(e, this.draggable),
   
);
 
}

 
const newDragTarget = this.workspace.getDragTarget(e);
 
if (this.dragTarget !== newDragTarget) {
   
// Call `onDragExit` then `onDragEnter`.
   
this.dragTarget?.onDragExit(this.draggable);
    newDragTarget
?.onDragEnter(this.draggable);
 
}
 
// Always call `onDragOver`
  newDragTarget
?.onDragOver(this.draggable);
 
this.dragTarget = newDragTarget;
}

Parar de arrastar

O método onEndDrag encerra uma ação de arrastar. Ele precisa notificar o elemento arrastável de que o arrastamento terminou e que o elemento foi descartado em qualquer destino de arrastamento que esteja sobre o cursor. Ele também precisa descartar o elemento arrastável se o destino de arrasto for uma área de exclusão.

  • O método onDrop sempre precisa ser chamado antes de outros métodos.
  • revertDrag precisa ser chamado se o destino de arrasto impedir o arrasto.
  • O método endDrag precisa ser chamado após reverter o arrasto, mas antes de descartar.
  • dispose precisa ser chamado se o destino de arrasto for uma área de exclusão.
onDragEnd(e) {
 
// Call `onDrop` first.
 
const dragTarget = this.workspace.getDragTarget(e);
 
if (dragTarget) {
   
this.dragTarget?.onDrop(this.draggable);
 
}

 
// Then revert the drag (if applicable).
 
if (this.shouldReturnToStart(e, this.draggable)) {
   
this.draggable.revertDrag();
 
}

 
// Then end the drag.
 
this.draggable.endDrag(e);

 
// Then delete the draggable (if applicable).
 
if (
    isDeletable
(this.draggable) &&
   
this.wouldDeleteDraggable(e, this.draggable)
 
) {
   
this.draggable.dispose();
 
}
}

Registro

Sua classe de arrasto precisa ser registrada para que possa ser criada quando os arrastamentos forem detectados.

// Note that the type is BLOCK_DRAGGER even though draggers drag more than
// blocks. The name is for backwards compatibility.
Blockly.registry.register(registry.Type.BLOCK_DRAGGER, 'MY_DRAGGER', MyDragger);

Uso

Depois de implementar o arrastador personalizado, é possível usá-lo transmitindo-o para a estrutura de configuração de injeção.

const myWorkspace = Blockly.inject('blocklyDiv', {
  plugins
: {
   
// Note that we pass this to blockDragger even though draggers drag more
   
// than blocks. The name is for backwards compatibility.
    blockDragger
: MyDragger,
 
},
});