גרירה

גורר הוא אובייקט של בקר שמרכז את משיכת רכיבים שניתן לגרור בתגובה לאינטראקציות של משתמשים.

יש מעט מאוד מצבים שבהם כדאי להטמיע רכיב גרירה בהתאמה אישית, כי אין הרבה דברים שתרצו להתאים אישית בנוגע לתיאום של גרירה. התוסף scroll-options מטמיע רכיב גרירה מותאם אישית כי הוא רוצה להוסיף גלילה בקצה של סביבת העבודה, וכך לשנות את האופן שבו קואורדינטות הפיקסלים מומרות לקווי הרוחב והאורך של סביבת העבודה.

תחומי אחריות

לגרירה יש כמה אחריות במהלך ביצוע גרירה:

  • קריאה לשיטות גרירה על הרכיב שניתן לגרירה.
  • חישוב המיקום שאליו רוצים לגרור את המשתמש בקואורדינטות של סביבת העבודה.
  • קריאה לשיטות של יעד גרירה בכל יעדי גרירה שמוצגים מעליהם עכבר.

הטמעה

כדי ליצור רכיב גרירה בהתאמה אישית, צריך להטמיע את הממשק 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 מסיימת גרירה. הוא צריך להודיע לרכיב הניתן לגרירה שהגרירה הסתיימה, ולכל יעד גרירה שמוצג מעליו שהרכיב הניתן לגרירה הופל. הוא צריך גם להיפטר מהרכיב שניתן לגרירה אם יעד הגרירה הוא אזור מחיקה.

  • תמיד צריך לקרוא ל-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);

שימוש

אחרי שמטמיעים את ה-dragger בהתאמה אישית, אפשר להעביר אותו למבנה של תצורת ההזרקה כדי להשתמש בו.

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