Un outil de glisser-déposer est un objet de contrôleur qui coordonne le glissement des éléments déplaçables en réponse aux interactions de l'utilisateur.
Il est très rare que vous souhaitiez implémenter un outil de glisser-déposer personnalisé, car il n'y a pas grand-chose que vous puissiez personnaliser concernant la coordination d'un glisser-déposer. Le plug-in de défilement d'options implémente un glisser-déposer personnalisé, car il souhaitait ajouter un défilement au bord de l'espace de travail, ce qui modifie la façon dont les coordonnées en pixels sont converties en coordonnées de l'espace de travail.
Responsabilités
Le dragger a plusieurs responsabilités lors de l'exécution des glissers:
- Appel des méthodes de glisser-déposer sur l'élément déplaçable.
- Calcul de la position à laquelle l'élément déplaçable doit se déplacer en coordonnées d'espace de travail.
- Appel des méthodes de cible de glissement sur les cibles de glissement sur lesquelles la souris est pointée.
Implémentation
Pour créer un outil de glisser-déposer personnalisé, vous devez implémenter l'interface IDragger
.
class MyDragger implements IDragger {
// Takes in the draggable being dragged and the workspace the drag
// is occurring in.
constructor(draggable, workspace);
}
Vous pouvez également sous-classer Blockly.dragging.Dragger
intégré, qui gère déjà les responsabilités de base.
Lancer le déplacement
La méthode onDragStart
initialise un glissement. Il doit stocker toutes les données nécessaires à l'exécution du glisser-déposer. Il doit également appeler startDrag
sur l'élément déplaçable en cours de déplacement.
onDragStart(e) {
this.startLoc = this.draggable.getRelativeToSurfaceXY();
this.draggable.startDrag(e);
}
Traînée
La méthode onDrag
exécute un glisser-déposer. Il doit calculer la nouvelle position de l'espace de travail pour l'élément déplaçable en fonction de totalDelta
, qui est indiqué en coordonnées de pixel.
Il doit également mettre à jour les cibles de glisser-déposer sur lesquelles vous pointez.
wouldDelete
doit toujours être appelé avant d'appeler d'autres hooks sur la cible de glisser-déposer.onDragExit
doit toujours être appelé sur l'ancienne cible de glisser-déposer avant d'appeleronDragEnter
sur la nouvelle cible de glisser-déposer.onDragOver
doit être appelé aprèsonDragEnter
la première fois que la cible de glissement est pointée, et à chaque appel supplémentaire deonDrag
lorsque la cible de glissement est toujours pointée.
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;
}
Arrêter les glissements
La méthode onEndDrag
met fin à un glissement. Il doit informer l'élément draggable que le glissement est terminé et toute cible de glissement survolée que l'élément draggable a été déposé. Il doit également supprimer l'élément déplaçable si la cible de glissement est une zone de suppression.
onDrop
doit toujours être appelé avant les autres méthodes.revertDrag
doit être appelé si la cible de glisser-déposer empêche les glissements.endDrag
doit être appelé après l'annulation du glissement, mais avant la suppression.dispose
doit être appelé si la cible de glisser-déposer est une zone de suppression.
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();
}
}
Inscription
Votre classe de dragger doit être enregistrée pour pouvoir être créée lorsque des glisser-déposer sont détectés.
// 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);
Utilisation
Une fois que vous avez implémenté votre outil de glisser-déposer personnalisé, vous pouvez l'utiliser en le transmettant à votre struct de configuration d'injection.
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,
},
});