I would like to change the preview while dragging an element. (see setDragImage)
Like using another element if the user hit ctrl or shift for instance while dragging ?
This is an example here. This example display an image when you start the drag action. However if you want to change it on the fly it's quite chanllenging !
Is it even possible ?
I don think it is possible by using only the native API since the setDragImage docs begin by "When a drag occurs, ...". Invoking setDragImage on other events does not thow error but does not seems to work.
However it is possible to implement a dynamic dragImage by using a custom sprite :
const areas=[
{
dom:document.querySelector('.zone-rabbits'),
headSprite:'🐰',
bodySprite:'🐇',
},
{
dom:document.querySelector('.zone-rats'),
headSprite:'🐭',
bodySprite:'🐀',
}
];
const traveller={
current:0,
dom: document.querySelector('.traveller')
};
const sprite=document.querySelector('.drag-sprite');
const blank=document.querySelector('.drag-blank');
const mouseMove=evt=>{
// Change sprite position
sprite.style.left=(evt.pageX-15)+'px';
sprite.style.top=(evt.pageY-15)+'px';
};
traveller.dom.draggable = true;
traveller.dom.ondragstart = evt => {
// Sets blank image so we can replace it with our sprite
evt.dataTransfer.setDragImage(blank, 0, 0);
// Init sprite contents ,visibility and position
sprite.innerHTML=areas[traveller.current].headSprite;
sprite.style.display='block';
mouseMove(evt);
};
traveller.dom.ondragend = evt => {
// Hide sprite
sprite.style.display='none';
};
areas.forEach((area,id)=>{
area.dom.ondragover = evt => {
evt.preventDefault();
// Move sprite
mouseMove(evt);
};
area.dom.ondragenter = evt => {
evt.preventDefault();
// Modify sprite
// NB : Sprite behaviour can be changed at any
// moment between dragstart & dragend
sprite.innerHTML = areas[id].headSprite;
};
area.dom.ondrop = evt => {
evt.preventDefault();
traveller.current=id;
traveller.dom.innerHTML=areas[id].bodySprite;
area.dom.appendChild(traveller.dom);
};
});
.world{
display:flex;
}
.zone{
width:100px;
height:100px;
border:solid 1px;
}
.zone-rats{
color:#00f;
background-color:#eef;
}
.zone-rabbits{
color:#f00;
background-color:#fee;
}
.traveller{
cursor:default;
}
.drag-sprite{
position:fixed;
/* drag image sprite and its contents
must not interfere with pointer events */
pointer-events:none;
}
.drag-blank{
width:'1px';
height:'1px';
opacity:0;
}
<div class="world">
<div class="zone zone-rabbits">
Rabbits
<div class="traveller">
🐇
</div>
</div>
<div class="zone zone-rats">
Rats
</div>
</div>
<div class="drag-sprite"></div>
<div class="drag-blank"></div>