פריט שניתן לגרירה הוא אובייקט שעבר רינדור וקיים בסביבת העבודה, ואפשר לגרור אותו ולשחרר אותו. הם מטמיעים את הממשק IDraggable
.
יש מעט מאוד מקרים שבהם כדאי להוסיף רכיב חדש שניתן לגרירה ל-Blockly (למשל, התוסף multiselect או שינוי האופן שבו אובייקט קיים מטפל בגרירות), כי אי אפשר להוסיף אובייקטים חדשים שעברו עיבוד ל-Blockly. האובייקטים המעובדים היחידים שיכולים להיות במרחב עבודה הם בלוקים, בועות ותגובות במרחב העבודה.
תחומי אחריות
לרכיבים שניתן לגרור יש כמה תפקידים במהלך הגרירה:
- העברת רכיבי SVG אל שכבת הגרירה.
- תרגום רכיבי SVG.
- הפעלת אירועים של תנועה.
הטמעה
כדי ליצור רכיב חדש שאפשר לגרור, צריך להטמיע את הממשקים IRenderedElement
ו-IDraggable
. כך Blockly יודע שהאובייקט גלוי ושאפשר לגרור אותו.
class MyDraggable extends IRenderedElement, IDraggable {}
החזרת רכיב ה-SVG הבסיסי
השיטה getRootSvg
מחזירה את רכיב ה-svg הבסיסי (בדרך כלל group) שמכיל את כל שאר הרכיבים שמרכיבים את התצוגה של הרכיב שניתן לגרירה.
getSvgRoot() {
return this.rootSvg;
}
החזרת ניידות
השיטה isMovable
מחזירה את הערך true אם אפשר להזיז את הרכיב הניתן לגרירה, ואת הערך false אם אי אפשר (יכול להיות שתרצו להשבית זמנית את האפשרות לגרור אובייקט). אם הפונקציה isMovable
מחזירה false
, סביבת העבודה נגררת במקום זאת.
isMovable() {
return true;
}
מיקום החזרה
השיטה getRelativeToSurfaceXY
מחזירה Coordinate
שמציין את המיקום של הפינה העליונה-התחלתית של הרכיב שניתן לגרירה בקואורדינטות של סביבת העבודה.
הקואורדינטות של סביבת העבודה מתחילות בפינה הימנית העליונה של סביבת העבודה. הם גם לא משתנים כשמבצעים שינוי גודל או העברה של סביבת העבודה.
getRelativeToSurfaceXY() {
return this.loc;
}
התחלת גרירה
השיטה startDrag
מאתחלת גרירה של הרכיב שאפשר לגרור. בשיטה הזו אי אפשר להזיז את הרכיב שניתן לגרירה. אבל כדאי לשמור את הנתונים או ליצור את האובייקטים שצריך כדי להשלים את הגרירה. הנתונים האלה כוללים את כל הנתונים שנדרשים כדי לבטל את הגרירה אם מתבצעת קריאה ל-revertDrag
.
בנוסף, צריך לשנות את רכיבי ה-SVG כך שיוצבו בשכבת הגרירה של סביבת העבודה, כדי שיוצגו מעל כל רכיב אחר.
הוא מקבל גם אירוע, שבו אפשר להשתמש כדי לבדוק אילו מקשים נלחצו. כך אפשר (לדוגמה) לטפל בגרירה תוך כדי החלפת הילוך בצורה שונה מגרירה רגילה.
startDrag(e) {
// Save the original location so we can revert the drag.
this.startLoc = this.getRelativeToSurfaceXY();
// Disable resizing the workspace for performance.
this.workspace.setResizesEnabled(false);
// Put the element on the drag layer.
this.workspace.getLayerManager()?.moveToDragLayer(this);
// Fire a drag event...
// etc...
}
גרירה
השיטה drag
מעבירה בפועל את האובייקט שניתן לגרירה. המיקום של newLoc
הוא בקואורדינטות של סביבת העבודה, ויש גם אירוע שמועבר שאפשר להשתמש בו כדי לבדוק אילו מקשים נלחצו.
drag(newLoc, e) {
this.moveTo(newLoc);
}
ביטול גרירות
השיטה revertDrag
מחזירה את הרכיב שניתן לגרירה למיקום שבו הוא היה בתחילת הגרירה. זה קורה אם, לדוגמה, הגרירה מסתיימת ביעד גרירה שמונע תנועה.
revertDrag() {
// Move back to the position that was stored in `startDrag`.
this.moveTo(this.startLoc);
}
סיום הגרירה
השיטה endDrag
מנקה את הגרירה, משחררת את כל הנתונים או האובייקטים המאוחסנים ומחזירה את הפריט שניתן לגרירה לשכבה המקורית שלו.
הפונקציה endDrag
תמיד נקראת אחרי revertDrag
אם revertDrag
נקראת.
endDrag() {
// Put the element back on its original layer (in this case BLOCK).
this.workspace
.getLayerManager()
?.moveOffDragLayer(this, Blockly.layers.BLOCK);
// Allow the workspace to start resizing again.
this.workspace.setResizesEnabled(true);
}
בחירה
הרכיב שנגרר נקבע לפי הרכיב שמסומן כשמזוהה גרירה.
ISelectable
כדי שאפשר יהיה לבחור רכיב שניתן לגרירה, הוא צריך להטמיע את הממשק ISelectable
.
class MyDraggable implements ISelectable {
constructor(workspace) {
this.id = Blockly.utils.idGenerator.genUid();
this.workspace = workspace;
}
select() {
// Visually indicate this draggable is selected.
}
unselect() {
// Visually indicate this draggable is not selected.
}
}
הגדרת הבחירה
אפשר להגדיר את הרכיב שנבחר באמצעות קריאה ל-Blockly.common.setSelected()
. בדרך כלל כדאי לעשות את זה בתגובה לאירוע pointerdown
מהמשתמש.
constructor() {
this.initSvg();
Blockly.browserEvents.conditionalBind(
this.getSvgRoot(),
'pointerdown',
this,
() => Blockly.common.setSelected(this));
}
תאימות
רכיב ה-draggable יכול להטמיע ממשקים נוספים כדי שיוכל ליצור אינטראקציה עם מערכות אחרות ב-Blockly.
פריטים שניתנים למחיקה
אפשר להטמיע את הממשק IDeleteable
כדי לאפשר השלכה של רכיבים שניתן לגרור לפח האשפה או ליעדי מחיקה אחרים.
class MyDraggable implements IDeletable {
isDeletable() {
return true;
}
dispose() {
// Dispose of any references to data or SVG elements.
}
setDeleteStyle() {
// Visually indicate that the draggable is about to be deleted.
}
}
ניתן להעתקה
אתם יכולים להטמיע את הממשק ICopyable
כדי לאפשר העתקה של הרכיב הניתן לגרירה, ולהגדיר את הממשק IPaster
כדי לאפשר הדבקה שלו.
מידע נוסף על העתקה והדבקה זמין במאמר בנושא העתקה והדבקה.