9

I am facing an issue, where I am dragging a div.

While the ghost element looks good on MacOs(yes both on Chrome and FireFox),it appears to be too transparent,in Windows (yes both on Chrome and FireFox. I tried multiple approaches but nothing seems to work. So is it possible to style the ghost element?

Also, I tried to make an image of that element on the go, and use it as ghost dragging image, but the transparency issue still remains.

ishan srivastava
  • 363
  • 1
  • 3
  • 10
  • did you try making a clone of the element and moving it with cursor ? cuz you can not modify the opacity of the ghost element. – Buzzinga Oct 24 '19 at 14:22
  • Yeah thats the last resort.. Are you sure that opacity is nonchangable? I saw it on trello, there the ghost elements are totally opaque. – ishan srivastava Oct 24 '19 at 14:25
  • 1
    it is handled by the browser so you can not change the opacity. You can define your own element or image. here is a discussion about the same topic: https://stackoverflow.com/a/10904112/682999 – Buzzinga Oct 24 '19 at 14:33
  • If you're dragging images, you can try this solution: https://www.kryogenix.org/code/browser/custom-drag-image.html – thdoan Jun 22 '23 at 05:49

1 Answers1

20

You can do this by implementing dragging of the element yourself in JavaScript. That way, you can apply a CSS class to the element while it is being dragged, which styles it in any way you wish.

const d = 'dragging';

const container = document.getElementById('container');
const el = document.getElementById('drag');

var cOffX = 0;
var cOffY = 0;

el.addEventListener('mousedown', dragStart);

function dragStart(e) {
  e = e || window.event;
  e.preventDefault();

  cOffX = e.clientX - el.offsetLeft;
  cOffY = e.clientY - el.offsetTop;

  document.addEventListener('mousemove', dragMove);
  document.addEventListener('mouseup', dragEnd);

  el.classList.add(d);
  container.style.cursor = 'move';
};

function dragMove(e) {
  e = e || window.event;
  e.preventDefault();

  el.style.top = (e.clientY - cOffY).toString() + 'px';
  el.style.left = (e.clientX - cOffX).toString() + 'px';
};

function dragEnd(e) {
  e = e || window.event;
  e.preventDefault();
  
  document.removeEventListener('mousemove', dragMove);
  document.removeEventListener('mouseup', dragEnd);

  el.classList.remove(d);
  container.style.cursor = null;
};
#container {
  width: 100vw;
  height: 100vh;
  margin: 0;
  padding: 0;
}

#drag {
  position: absolute;
  height: 100px;
  width: 100px;
  background-color: lime;
  border-radius: 0;
  transition: background-color 0.25s, border-radius 0.25s;
  cursor: move;
}

#drag.dragging {
  background-color: navy;
  border-radius: 50%;
}
<div id="container">
  <div id="drag"></div>
</div>

As others have said, the ghosting is browser-based and can't be changed, so it seems you need your own solution if you want to get around that.

sbgib
  • 5,580
  • 3
  • 19
  • 26
  • 4
    This is exactly what I ended up doing. SIdenote for future readers though, the one thing you can do with the ghost image apparently is change the image itself using [setDragImage](https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage). Important quote from that page: `The image will typically be an element but it can also be a or any other visible element.` So there might be some leeway there if you play with it....a canvas, of course, can contain anything. – temporary_user_name Sep 18 '20 at 06:32
  • I appreciate your comment, a simple `.on('dragstart', e => e.preventDefault())` in the example from that MDN page solved my issue. – CPHPython Dec 16 '21 at 18:27