Loading...
Drag and drop based on [PointerEvents](/en/api/event#interaction events). In this example, we listen to the drag event of the soccer ball to move it to the right position and the dragover event of the goal to change the transparency when the soccer ball crosses the goal area.
import { Renderer as CanvasRenderer } from '@antv/g-canvas';import { Plugin } from '@antv/g-plugin-dragndrop';const canvasRenderer = new CanvasRenderer();canvasRenderer.registerPlugin(new Plugin());
We provide the following configuration items that can be passed in when creating plugins, for example overlap.
new Plugin({overlap: 'center',});
Since there is no "style" on Document, when we want to drag and drop on a blank area of the canvas, we cannot do so.
// wrongcanvas.document.style.draggable = true;// correctconst plugin = new Plugin({// we can drag the whole document from empty space now!isDocumentDraggable: true,});
In this example, dragging in a blank area pans the camera with camera.pan() to achieve the visual effect of the entire canvas moving.
const camera = canvas.getCamera();canvas.addEventListener('drag', function (e) {if (e.target === canvas.document) {camera.pan(-e.movementX, -e.movementY);}});
In the above example we have e.target === canvas.document
to avoid moving non-Document elements like "soccer". element also causes the camera to move.
Similarly, if we want to make Document a "placeable area", we can use this configuration item.
// wrongcanvas.document.style.droppable = true;// correctconst plugin = new Plugin({isDocumentDroppable: true,});
In this example, when we drag the soccer to a blank area, the console prints the following message.
canvas.addEventListener('drop', function (e) {if (e.target === canvas.document) {console.log('drop on document');}});
We provide the following configurations for what conditions are met to determine dragstart
: based on drag distance and time, respectively. Only if all these conditions are met, a series of drag events such as dragstart
will be triggered.
This configuration item is used to configure the detection threshold of the drag distance in pixels, and only greater than this value will be passed. The default value is 0.
In this example, we have configured this option to 10, i.e. only dragging more than 10 pixels will trigger a drag event.
const plugin = new Plugin({dragstartDistanceThreshold: 10,});
This configuration item is used to configure the detection threshold of drag and drop time in milliseconds, and only greater than this value will be passed. The default value is 0.
In this example, we have configured this option to 100, i.e. the drag event will only be triggered if the drag exceeds 100 milliseconds.
const plugin = new Plugin({dragstartTimeThreshold: 100,});
Used to determine if the graph in the drag is in the dropzone
, supports the following two values.
'pointer'
Default value. The mouse position enters the dropzone
area by determining'center'
The center of the dropzone is determined if the center of the dropzone is in the dropzone.In addition to passing in when the plugin is initialized, you can also use setOptions
to modify the above configuration items at any time later:
plugin.setOptions({dragstartTimeThreshold: 200,});
Drag and Drop related events are both bubbly.
After registering the plugin, you need to set the draggable
property to true
in order to make the graphics support drag and drop. For example, for the soccer ball above.
const ball = new Image({style: {draggable: true, // 表示该图形支持拖拽x: 300,y: 200,width: 100,height: 100,src: 'https://en.js.cx/clipart/ball.svg',cursor: 'pointer',},});
At this point, you can listen to drag-related events for the graph, including the following three types of events, the target of the event object are the graph being dragged.
drag The related events are all [PointerEvents](/en/api/event#interaction events), so you can access the properties on the event object in the event listener.
For example, when we start dragging, we record the offset from mouse position to the position of the dragged element shiftX/Y
, both under Canvas/world coordinate system. In the drag
event we call setPosition to finish the panning of the dragged drawing.
https://javascript.info/mouse-drag-and-drop#correct-positioning
let shiftX = 0;let shiftY = 0;function moveAt(target, canvasX, canvasY) {target.setPosition(canvasX - shiftX, canvasY - shiftY);}ball.addEventListener('dragstart', function (e) {e.target.style.opacity = 0.5;ballText.style.text = 'ball dragstart';const [x, y] = e.target.getPosition();shiftX = e.canvasX - x;shiftY = e.canvasY - y;moveAt(e.target, e.canvasX, e.canvasY);});ball.addEventListener('drag', function (e) {moveAt(e.target, e.canvasX, e.canvasY);ballText.style.text = `ball drag movement: ${e.movementX}, ${e.movementY}`;});ball.addEventListener('dragend', function (e) {e.target.style.opacity = 1;ballText.style.text = 'ball dragend';});
Similarly, we can enable droppable
for graphics that support placement.
const gate = new Image({style: {droppable: true, // Indicates that the graph supports the placement ofx: 50,y: 100,width: 200,height: 100,src: 'https://en.js.cx/clipart/soccer-gate.svg',},});
At this point you can listen to drag/drop related events in the placement area, including the following three types of events, the target of the event object are the graphics of the placement area.
For example, let's have the goal listen for events related to.
gate.addEventListener('dragenter', function (e) {e.target.style.opacity = 0.6;gateText.style.text = 'gate dragenter';});gate.addEventListener('dragleave', function (e) {e.target.style.opacity = 1;gateText.style.text = 'gate dragleave';});gate.addEventListener('dragover', function (e) {e.target.style.opacity = 0.6;gateText.style.text = 'gate dragover';});gate.addEventListener('drop', function (e) {e.target.style.opacity = 1;gateText.style.text = 'gate drop';});
The drag
series of events has a sequential triggering order with other interaction events. Take the pointer
series of events as an example, in a typical drag and drop process, the following events are triggered in sequence.
pointerdown
presspointermove * n
dragging a certain distance, and then the dragging process will be decideddragstart
Start draggingdrag
Dragging in progresspointermove
drag
draggingpointermove
drag
draggingpointermove
dragend
end of dragpointerup
liftingIn the Drag'n'drop implementation of HTML, only one click
and drag
event will be triggered at the same time: https://plnkr.co/edit/5mdl7oTg0dPWXIip
We have also kept this setting in our implementation, so that click
is not triggered after the dragend
event is fired.