드래거는 사용자 상호작용에 응답하여 드래그하는 드래그 가능한 항목을 조정하는 컨트롤러 객체입니다.
드래그 조정에 관해 맞춤설정할 만한 사항이 많지 않으므로 맞춤 드래거를 구현해야 하는 상황은 거의 없습니다. scroll-options 플러그인은 작업공간 가장자리에 스크롤을 추가하여 픽셀 좌표가 작업공간 좌표로 변환되는 방식을 변경하기 위해 맞춤 드래거를 구현합니다.
책임
드래거는 드래그를 실행할 때 다음과 같은 몇 가지 책임이 있습니다.
- draggable에서 drag 메서드를 호출합니다.
- 드래그 가능한 요소가 워크스페이스 좌표로 이동해야 하는 위치를 계산합니다.
- 마우스 오버된 드래그 타겟에서 드래그 타겟 메서드를 호출합니다.
구현
맞춤 드래거를 만들려면 IDragger 인터페이스를 구현해야 합니다.
class MyDragger implements IDragger {
// Takes in the draggable being dragged and the workspace the drag
// is occurring in.
constructor(draggable, workspace);
}
이미 기본 책임을 처리하는 기본 제공 Blockly.dragging.Dragger를 서브클래스화할 수도 있습니다.
드래그 시작
onDragStart 메서드는 드래그를 초기화합니다. 드래그를 실행하는 데 필요한 데이터를 저장해야 합니다. 또한 드래그되는 드래그 가능한 요소에서 startDrag를 호출해야 합니다.
onDragStart(e) {
this.startLoc = this.draggable.getRelativeToSurfaceXY();
this.draggable.startDrag(e);
}
드래그
onDrag 메서드는 드래그를 실행합니다. 드래그 가능한 요소의 새 작업공간 위치를 계산해야 합니다. 이 위치는 픽셀 좌표로 제공되는 totalDelta를 기반으로 계산됩니다.
마우스 오버 중인 모든 드래그 타겟도 업데이트해야 합니다.
wouldDelete는 항상 드래그 타겟의 다른 후크를 호출하기 전에 호출해야 합니다.- 새 드래그 타겟에서
onDragEnter를 호출하기 전에 항상 이전 드래그 타겟에서onDragExit를 호출해야 합니다. onDragOver는 드래그 타겟이 처음으로 마우스 오버될 때onDragEnter후에 호출되어야 하며, 드래그 타겟이 여전히 마우스 오버된 상태인onDrag의 추가 호출 시마다 호출되어야 합니다.
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;
}
드래그 종료
onEndDrag 메서드는 드래그를 종료합니다. 드래그가 종료되었음을 draggable에 알리고 마우스 오버된 드래그 타겟에 draggable이 떨어졌음을 알립니다. 또한 드래그 타겟이 삭제 영역인 경우 draggable을 폐기해야 합니다.
onDrop는 항상 다른 메서드보다 먼저 호출해야 합니다.- 드래그 타겟이 드래그를 방해하는 경우
revertDrag를 호출해야 합니다. endDrag는 드래그를 되돌린 후, 그러나 삭제하기 전에 호출해야 합니다.- 드래그 타겟이 삭제 영역인 경우
dispose를 호출해야 합니다.
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();
}
}
등록
드래그가 감지될 때 생성될 수 있도록 드래거 클래스를 등록해야 합니다.
// 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);
사용
맞춤 드래거를 구현한 후 구성 옵션에 전달하여 사용할 수 있습니다.
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,
},
});