ember-drag-drop
ember-drag-drop copied to clipboard
Possible to use setDragImage() to use a custom drag image?
Tried using dragStartHook
, but I don't think that's the correct place. Any pointers?
Hey glad you asked this question. I have a similar task where I need to customize the drag image and am trying to modify the ghost image without any luck. I tried the following method but the drag image is not updating.
Anyone else had any luck customizing the drag image?
dragStartAction(event){
let clonedItem = event.target.cloneNode(true);
clonedItem.style.position = "absolute";
clonedItem.style.background = "red";
clonedItem.style.top = "0px";
clonedItem.style.right = "0px";
document.body.appendChild(clonedItem);
event.dataTransfer.setDragImage(clonedItem, 0 ,0 );
}
+1
You need to use dragStartAction='dragStartAction'
instead of dragStartHook=(action 'dragStartAction')
because of this:
https://github.com/mharris717/ember-drag-drop/blob/master/addon/components/draggable-object.js#L78-L83
Anyone else had any luck customizing the drag image?
yup.
First of all, the dragStartAction
actions works with 2 arguments (obj, event)
, see:
this.get('dragStartAction')(obj, event);
Source: https://github.com/mharris717/ember-drag-drop/blob/v0.9.0-beta.0/addon/components/draggable-object.js#L115
Hence, the replacement:
dragStartAction(object, event){
let clonedItem = event.target.cloneNode(true);
clonedItem.style.position = "absolute";
clonedItem.style.background = "red";
clonedItem.style.top = "0px";
clonedItem.style.right = "0px";
document.body.appendChild(clonedItem);
event.dataTransfer.setDragImage(clonedItem, 0 ,0 );
}
should make it works.
Apart from that, the setDragImage
needs the existed node in DOM, the document.body.appendChild(clonedItem);
solves this, but I think it's better to use the Ember component for this to have full customization ability, for example, we can use https://github.com/lifeart/ember-ref-bucket for this reference or archived alternative https://github.com/lifeart/ember-ref-modifier.
The implementation looks like this:
app/components/draggable-item.hbs
<DraggableObject
@dragStartAction={{this.onDragStart}}
>
</DraggableObject>
app/components/draggable-item.js
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { globalRef } from 'ember-ref-bucket';
export default class DraggableItemComponent extends Component {
@globalRef('draggableNode') draggableNode = null;
@action
onDragStart(object, event) {
const x = 0;
const y = 0;
event.dataTransfer.setDragImage(this.draggableNode, x, y);
}
}
app/components/drag-item.js
<div
class="absolute -left-full"
{{create-global-ref "draggableNode"}}
...attributes
>
"We can use here any components with full customization ability"
</div>
the classes absolute -left-full
takes from https://tailwindcss.com/ it needs to move this node out of the visible screen, in CSS way it looks like this:
position: absolute;
left: -100%;
app/templates/application.hbs
or anywhere you want just to have global reference:
...
<DragItem/>
...