akserg / ng2-dnd

Angular 2 Drag-and-Drop without dependencies
MIT License
840 stars 252 forks source link

[Question] How to style the cloned item instead of the dragged item #146

Open vamidi opened 7 years ago

vamidi commented 7 years ago

I'm submitting a feature request

nodehack commented 7 years ago

I'm not sure this is possible with the current limitations of html5 drag and drop. Each browser handles the draggable differently. In chrome you can do a little hacking around to get your desired effect like so:

  1. Capture the draggable components and add event listeners for their drag events.
  2. Hook into dragstart and dragend to create a cloned element.
  3. Style the element that stays behind with .dnd-drag-start.
  4. Style the element you want to move with .clone. Note that transformations do not seem to work when styling this element. This element must be visible but can be "hidden" using z-index.
  5. Set the cloned element as the drag image.

Example code:

import { Component, ViewChildren, QueryList } from '@angular/core';
import { DraggableComponent } from 'ng2-dnd';

@Component({
  selector: 'foo'
  templateUrl: './foo.html',  //some template that has elements with dnd-draggable attribute
  styleUrls: ['./foo.css']
})

export class FooComponent {
  @ViewChildren(DraggableComponent) draggables: QueryList<DraggableComponent>;
  private clone: HTMLElement;  

  ngAfterViewInit () {
    this.draggables.changes.subscribe(() => {
      this.draggables.forEach((ref) => {
        ref._elem.addEventListener('dragstart', (event) => {
          this.clone = <HTMLElement>event.srcElement.cloneNode(true);
          this.clone.classList.remove('dnd-drag-start');
          this.clone.classList.add('clone');
          document.body.appendChild(this.clone);
          event.dataTransfer.setDragImage(this.clone, 0, 0);
        }, false);
        ref._elem.addEventListener('dragend', (event) =>  {
          document.body.removeChild(this.clone);
        }, false);
      });
    });
  }
}

foo.css

.dnd-drag-start {
  background-color: blue;
}

.clone {
  background-color: red;
  position: absolute;
  top: 0px;
  right: 0px;
  z-index: -1;
}

Lots of good info about drag and drop ghosting here.