Penarik kustom

Penggerak adalah objek pengontrol yang mengoordinasikan penarikan objek yang dapat ditarik sebagai respons terhadap interaksi pengguna.

Ada sangat sedikit situasi yang mengharuskan Anda menerapkan pengontrol tarik kustom, karena tidak banyak hal yang mungkin ingin Anda sesuaikan terkait koordinasi tarik. Plugin scroll-options menerapkan penggeser kustom karena ingin menambahkan scroll di tepi ruang kerja, yang mengubah cara koordinat piksel dikonversi menjadi koordinat ruang kerja.

Tanggung Jawab

Penggerak memiliki beberapa tanggung jawab saat menjalankan tarik:

  • Memanggil metode tarik pada elemen yang dapat ditarik.
  • Menghitung posisi yang harus dipindahkan oleh elemen yang dapat ditarik dalam koordinat workplace.
  • Memanggil metode target tarik pada target tarik yang diarahkan kursor.

Penerapan

Untuk membuat penggeser kustom, Anda harus mengimplementasikan antarmuka IDragger.

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

Anda juga dapat membuat subclass Blockly.dragging.Dragger bawaan, yang sudah menangani tanggung jawab dasar.

Memulai operasi tarik

Metode onDragStart melakukan inisialisasi tarik. Fungsi ini harus menyimpan data apa pun yang diperlukan untuk menjalankan tarik. Fungsi ini juga harus memanggil startDrag pada elemen yang dapat ditarik yang sedang ditarik.

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

  this.draggable.startDrag(e);
}

Tarik

Metode onDrag menjalankan tarik. Fungsi ini akan menghitung posisi ruang kerja baru untuk elemen yang dapat ditarik berdasarkan totalDelta, yang diberikan dalam koordinat piksel.

Tindakan ini juga akan memperbarui target tarik yang diarahkan kursor.

  • wouldDelete harus selalu dipanggil sebelum memanggil hook lain pada target tarik.
  • onDragExit harus selalu dipanggil pada target tarik lama sebelum memanggil onDragEnter pada target tarik baru.
  • onDragOver harus dipanggil setelah onDragEnter saat pertama kali target tarik diarahkan, dan pada setiap panggilan tambahan ke onDrag saat target tarik masih diarahkan.
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;
}

Mengakhiri tarik

Metode onEndDrag mengakhiri tarik. Tindakan ini akan memberi tahu elemen yang dapat ditarik bahwa tindakan tarik telah berakhir dan target tarik yang diarahkan kursor bahwa elemen yang dapat ditarik telah dilepaskan. Fungsi ini juga harus membuang elemen yang dapat ditarik jika target tarik adalah area hapus.

  • onDrop harus selalu dipanggil sebelum metode lain.
  • revertDrag harus dipanggil jika target tarik mencegah tarik.
  • endDrag harus dipanggil setelah mengembalikan tarik, tetapi sebelum dibuang.
  • dispose harus dipanggil jika target tarik adalah area hapus.
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();
  }
}

Pendaftaran

Class penggeser Anda harus didaftarkan agar dapat dibuat saat penarikan terdeteksi.

// 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);

Penggunaan

Setelah menerapkan penggeser kustom, Anda dapat menggunakannya dengan meneruskannya ke opsi konfigurasi.

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