Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to resize using angular material drag and drop

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?

like image 586
Karam Avatar asked Nov 02 '25 03:11

Karam


1 Answers

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.

like image 187
Anjana Silva Avatar answered Nov 03 '25 20:11

Anjana Silva