4

I am creating a web app using Angular and Material, I want to be able to drag, drop and resize my sections. Is there a way it can be done using Angular Material drag and drop CDK?

slasky
  • 2,726
  • 4
  • 27
  • 36
Karam
  • 336
  • 5
  • 18
  • you can check my problems and visit linked site. https://stackoverflow.com/questions/61846413/angular-material-multi-objects-drag-and-drop-with-resizing-problem – ganggaroo May 17 '20 at 21:50

2 Answers2

4

If you are looking for a "non-third-party dependent" solution, then the following is the best.

The following has been tested against Angular 9.

The original example

The folked version (same as above, in case if the original gets deleted)

HTML

<div #resizeBox class="container" style="position: relative;" [style.width.px]="width"
  [style.height.px]="height">
  <span #dragHandleCorner [cdkDragLockAxis]="lockAxis" class="dragHandle corner" cdkDrag (cdkDragMoved)="dragMove(dragHandleCorner, $event)"></span>
  <span #dragHandleRight cdkDragLockAxis="x" class="dragHandle right" cdkDrag (cdkDragMoved)="dragMove(dragHandleRight, $event)"></span>
  <span #dragHandleBottom cdkDragLockAxis="y" class="dragHandle bottom" cdkDrag (cdkDragMoved)="dragMove(dragHandleBottom, $event)"></span>
  <span class="full" style="width: 100%;">Hello World!</span>
</div>

Component.ts

import { CdkDragMove } from '@angular/cdk/drag-drop';
import { AfterViewInit, Component, ElementRef, NgZone, ViewChild } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {
  @ViewChild('resizeBox') resizeBox: ElementRef;
  @ViewChild('dragHandleCorner') dragHandleCorner: ElementRef;
  @ViewChild('dragHandleRight') dragHandleRight: ElementRef;
  @ViewChild('dragHandleBottom') dragHandleBottom: ElementRef;



  get resizeBoxElement(): HTMLElement {
    return this.resizeBox.nativeElement;
  }

  get dragHandleCornerElement(): HTMLElement {
    return this.dragHandleCorner.nativeElement;
  }

  get dragHandleRightElement(): HTMLElement {
    return this.dragHandleRight.nativeElement;
  }

  get dragHandleBottomElement(): HTMLElement {
    return this.dragHandleBottom.nativeElement;
  }

  constructor(private ngZone: NgZone) {}

  ngAfterViewInit() {
    this.setAllHandleTransform();
  }

  setAllHandleTransform() {
    const rect = this.resizeBoxElement.getBoundingClientRect();
    this.setHandleTransform(this.dragHandleCornerElement, rect, 'both');
    this.setHandleTransform(this.dragHandleRightElement, rect, 'x');
    this.setHandleTransform(this.dragHandleBottomElement, rect, 'y');
  }

  setHandleTransform(
    dragHandle: HTMLElement,
    targetRect: ClientRect | DOMRect,
    position: 'x' | 'y' | 'both'
  ) {
    const dragRect = dragHandle.getBoundingClientRect();
    const translateX = targetRect.width - dragRect.width;
    const translateY = targetRect.height - dragRect.height;

    if (position === 'x') {
      dragHandle.style.transform = `translate3d(${translateX}px, 0, 0)`;
    }

    if (position === 'y') {
      dragHandle.style.transform = `translate3d(0, ${translateY}px, 0)`;
    }

    if (position === 'both') {
      dragHandle.style.transform = `translate3d(${translateX}px, ${translateY}px, 0)`;
    }
  }

  dragMove(dragHandle: HTMLElement, $event: CdkDragMove<any>) {
    this.ngZone.runOutsideAngular(() => {
      this.resize(dragHandle, this.resizeBoxElement);
    });
  }

  resize(dragHandle: HTMLElement, target: HTMLElement) {
    const dragRect = dragHandle.getBoundingClientRect();
    const targetRect = target.getBoundingClientRect();

    const width = dragRect.left - targetRect.left + dragRect.width;
    const height = dragRect.top - targetRect.top + dragRect.height;

    target.style.width = width + 'px';
    target.style.height = height + 'px';

    this.setAllHandleTransform();
  }
}

CSS

.container {
  position: relative;
  background-color: gray;
}

.full {
  width: 100%;
  background: yellow;
}

.dragHandle {
  position: absolute;
  background-color: red;
}

.dragHandle.corner {
  width: 15px;
  height: 15px;
  cursor: nwse-resize;
}

.dragHandle.right {
  width: 2px;
  height: 100%;
  cursor: ew-resize;
}

.dragHandle.bottom {
  height: 2px;
  width: 100%;
  cursor: ns-resize;
}

Hope this helps some one :)

Thanks.

Anjana Silva
  • 8,353
  • 4
  • 51
  • 54
0

For resize window:(JQlite)

 angular.element($window).triggerHandler('resize');