دراگر

دراگر یک شی کنترل کننده است که کشیدن قابل کشیدن را در پاسخ به تعاملات کاربر هماهنگ می کند.

شرایط بسیار کمی وجود دارد که بخواهید یک کشنده سفارشی را پیاده سازی کنید، زیرا موارد زیادی وجود ندارد که بخواهید در مورد هماهنگی کشیدن آن را سفارشی کنید. افزونه 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 همیشه باید قبل از فراخوانی قلاب های دیگر در هدف درگ فراخوانی شود.
  • قبل از فراخوانی 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 به یک کشیدن پایان می دهد. باید به کشنده اطلاع دهد که کشیدن به پایان رسیده است و هر هدف درگ شناور شده ای که قابل کشیدن رها شده است. همچنین اگر هدف کشیدن یک منطقه حذف است، باید قابلیت کشیدن را از بین ببرد.

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