드래거는 사용자 상호작용에 응답하여 드래그하는 드래그 가능한 항목을 조정하는 컨트롤러 객체입니다.
드래그 조정에 관해 맞춤설정할 만한 사항이 많지 않으므로 맞춤 드래거를 구현해야 하는 상황은 거의 없습니다. 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,
},
});