นักลากที่กำหนดเอง

ตัวลากคือออบเจ็กต์ตัวควบคุมที่ประสานการลากรายการที่ลากได้เพื่อตอบสนองต่อการโต้ตอบของผู้ใช้

มีบางกรณีที่คุณอาจต้องการใช้เครื่องมือลากที่กำหนดเอง เนื่องจากมีการปรับแต่งไม่มากนักเกี่ยวกับการประสานการลาก ปลั๊กอิน scroll-options ใช้เครื่องมือลากที่กำหนดเองเนื่องจากต้องการเพิ่มการเลื่อนที่ขอบของพื้นที่ทำงาน ซึ่งจะเปลี่ยนวิธีแปลงพิกัดพิกเซลเป็นพิกัดพื้นที่ทำงาน

หน้าที่รับผิดชอบ

ผู้ลากมีหน้าที่หลายประการเมื่อทำการลาก

  • การเรียกใช้เมธอดการลากในรายการที่ลากได้
  • การคำนวณตำแหน่งที่รายการที่ลากได้ควรย้ายไปในรูปแบบพิกัดของพื้นที่ทํางาน
  • การเรียกใช้เมธอด drag target บนเป้าหมายการลากที่วางเมาส์เหนือ

การใช้งาน

หากต้องการสร้างตัวลากที่กำหนดเอง คุณต้องใช้อินเทอร์เฟซ 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 ก่อนเรียกใช้ฮุกอื่นๆ บนเป้าหมายการลากเสมอ
  • คุณควรเรียกใช้ onDragExit กับเป้าหมายการลากเดิมเสมอก่อนที่จะเรียกใช้ onDragEnter กับเป้าหมายการลากใหม่
  • 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 นั้นถูกวางแล้ว และควรกำจัดรายการที่ลากได้หากเป้าหมายการลากเป็นพื้นที่ลบ

  • 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,
  },
});