Có thể kéo là một đối tượng đã kết xuất hình ảnh tồn tại trong không gian làm việc và có thể kéo và thả. Họ triển khai giao diện IDraggable
.
Có rất ít trường hợp bạn muốn thêm một đối tượng mới có thể kéo vàoBlockly (ví dụ: trình bổ trợ chọn nhiều lần hoặc thay đổi cách một đối tượng hiện có xử lý các thao tác kéo), vì bạn không thể thêm đối tượng mới kết xuất vào Blockly. Các đối tượng được kết xuất duy nhất có thể tồn tại trong không gian làm việc là các khối, bong bóng trò chuyện và nhận xét trong không gian làm việc.
Yêu cầu của công việc
Thành phần có thể kéo có một số trách nhiệm khi thực thi thao tác kéo:
Triển khai
Để tạo một thành phần có thể kéo mới, bạn phải triển khai giao diện IRenderedElement
và IDraggable
. Điều này cho phép Blockly biết rằng đối tượng của bạn đang hiển thị và có thể được kéo.
class MyDraggable extends IRenderedElement, IDraggable {}
Trả về phần tử SVG gốc
Phương thức getRootSvg
trả về phần tử svg gốc (thường là một nhóm) chứa mọi phần tử khác tạo nên khung hiển thị cho đối tượng có thể kéo được.
getSvgRoot() {
return this.rootSvg;
}
Khả năng di chuyển của lượt trả về
Phương thức isMovable
sẽ trả về xem hiện có thể di chuyển đối tượng có thể kéo hay không (vì bạn có thể tạm thời tắt tính năng kéo một đối tượng). Nếu isMovable
trả về false
, thì không gian làm việc sẽ được kéo.
isMovable() {
return true;
}
Vị trí trả hàng
Phương thức getRelativeToSurfaceXY
trả về một Coordinate
chỉ định vị trí góc bắt đầu trên cùng của đối tượng có thể kéo trong toạ độ không gian làm việc.
Toạ độ không gian làm việc có gốc ở góc bên trái tuyệt đối và phía trên cùng tuyệt đối của không gian làm việc. Đồng thời, chúng sẽ không thay đổi khi không gian làm việc được điều chỉnh theo tỷ lệ hoặc di chuyển.
getRelativeToSurfaceXY() {
return this.loc;
}
Bắt đầu kéo
Phương thức startDrag
khởi chạy thao tác kéo vào đối tượng có thể kéo. Phương thức này không di chuyển phần có thể kéo. Tuy nhiên, bạn nên lưu trữ mọi dữ liệu hoặc tạo bất kỳ đối tượng nào cần thiết để hoàn thành quá trình kéo. Điều này bao gồm mọi dữ liệu cần thiết để đảo ngược lệnh kéo nếu revertDrag
được gọi.
Bạn cũng nên thay đổi các phần tử svg để nằm trên lớp kéo của không gian làm việc, để chúng tồn tại phía trên mọi thành phần khác.
Tính năng này cũng tham gia một sự kiện mà bạn có thể dùng để kiểm tra xem có phím đã nhấn hay không. Điều này cho phép (chẳng hạn như) bạn xử lý thao tác kéo trong khi dịch chuyển khác với thao tác kéo thông thường.
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...
}
Phương trình lực cản
Phương thức drag
thực sự di chuyển đối tượng có thể kéo. newLoc
nằm trong toạ độ không gian làm việc và cũng có một sự kiện được truyền qua mà bạn có thể sử dụng để kiểm tra các phím đã nhấn.
drag(newLoc, e) {
this.moveTo(newLoc);
}
Huỷ bỏ các thao tác kéo
Phương thức revertDrag
trả về vị trí có thể kéo khi bắt đầu kéo. Chẳng hạn, hiện tượng này xảy ra nếu mục có thể kéo được thả vào mục tiêu kéo đang ngăn cản chuyển động.
revertDrag() {
// Move back to the position that was stored in `startDrag`.
this.moveTo(this.startLoc);
}
Kết thúc kéo
Phương thức endDrag
dọn dẹp thao tác kéo, giải phóng mọi dữ liệu hoặc đối tượng đã lưu trữ và đưa đối tượng có thể kéo về lớp ban đầu.
endDrag
luôn được gọi sau revertDrag
nếu revertDrag
được gọi.
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);
}
Lựa chọn
Phần tử được kéo được xác định theo phần tử được chọn khi phát hiện thao tác kéo.
ISelectable
Để được chọn, thành phần có thể kéo phải triển khai giao diện 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.
}
}
Đặt lựa chọn
Bạn có thể đặt phần tử đã chọn bằng cách gọi Blockly.common.setSelected()
. thường, bạn cần thực hiện việc này
để phản hồi sự kiện pointerdown
của người dùng.
constructor() {
this.initSvg();
Blockly.browserEvents.conditionalBind(
this.getSvgRoot(),
'pointerdown',
this,
() => Blockly.common.setSelected(this));
}
Khả năng tương thích
Thành phần kéo được của bạn có thể triển khai các giao diện bổ sung để có thể tương tác với các hệ thống khác trong Blockly.
Có thể xóa
Bạn có thể triển khai giao diện IDeleteable
để cho phép thao tác kéo có thể được xử lý bằng thùng rác hoặc các mục tiêu xoá khác.
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.
}
}
Có thể sao chép
Bạn có thể triển khai giao diện ICopyable
để cho phép sao chép nội dung có thể kéo và xác định IPaster
để cho phép dán nội dung đó.
Để biết thêm thông tin về cách sao chép và dán, hãy xem bài viết Sao chép và dán.