I am adding a resize functionality following a codepen example mentioned in the comments using MARGIN=4 (here I was not able to add the codepen link) The codepen was the best working example which I could find.
Have added 4 elements on all the 4 edges of the box.
I Have added hostlisteners to pointerdown , pointermove and pointerup but I am stuck with executing the animate() function present in Resizable directive.
In the directive the code has mainly 3 functions doing all the calculations onDown() , calc(e), animate()
import { Directive,
ElementRef,
HostListener } from '@angular/core';
import { DraggableDirective } from './draggable.directive';
@Directive({
selector: '[appResizable]' // Attribute selector
})
export class ResizableDirective extends DraggableDirective{
constructor(public element:ElementRef){
super(element);
}
minWidth = 60;
minHeight = 40;
// Thresholds
MARGINS = 4;
//End Of whats configurable
clicked = null;
public onRightEdge; onBottomEdge; onLeftEdge; onTopEdge;
public b; x; y;
redraw = false;
e;
clickedDragging = false;
ngOnInit(){
this.animate()
}
@HostListener('dragStart', ['$event'])
onDragStart(e:PointerEvent): void{
this.clickedDragging = true;
this.onDown(e);
e.preventDefault();
}
@HostListener('dragMove', ['$event'])
onDragMove(ee): void{
if (!this.dragging || ee.pointerId !== this.pointerId) {
return;
}
if((<HTMLElement>event.srcElement).id === ('side-top')){
this.onMove(ee);
ee.preventDefault();
}
}
@HostListener('dragEnd', ['$event'])
ondragend(ev): void{
this.onUp(ev);
}
onMove(ee){
if (!this.dragging || ee.pointerId !== this.pointerId) {
return;
}
if(this.clickedDragging){
this.calc(ee);
this.e = ee;
this.redraw = true;
}
}
onDown(e){
this.calc(e);
let isResizing = this.onRightEdge || this.onBottomEdge ||
this.onLeftEdge || this.onTopEdge;
this.clicked = {
x: this.x,
y: this.y,
cx: e.clientX,
cy: e.clientY,
w: this.b.width,
h: this.b.height,
isResizing: isResizing,
onRightEdge: this.onRightEdge,
onBottomEdge: this.onBottomEdge,
onLeftEdge: this.onLeftEdge,
onTopEdge: this.onTopEdge,
}
}
calc(e){
this.b = this.element.nativeElement.getBoundingClientRect();
this.x = e.clientX - this.b.left;
this.y = e.clientY - this.b.top;
this.onRightEdge = this.x >= this.b.width - this.MARGINS;
this.onBottomEdge = this.y >= this.b.height - this.MARGINS;
this.onLeftEdge = this.x < this.MARGINS;
this.onTopEdge = this.y < this.MARGINS;
}
animate(){
requestAnimationFrame(this.animate);
if(!this.redraw)return;
this.redraw = false;
if(this.clicked && this.clicked.isResizing){
if(this.clicked.onRightEdge){
this.element.nativeElement.style.width = Math.max(this.x,
this.minWidth) + 'px';
}
if(this.clicked.onBottomEdge){
this.element.nativeElement.style.height = Math.max(this.y,
this.minHeight) + 'px';
}
if(this.clicked.onLeftEdge){
let currentWidth = Math.max(this.clicked.cx -
this.e.clientX + this.clicked.w, this.minWidth);
if(currentWidth > this.minWidth){
this.element.nativeElement.style.width = currentWidth + 'px';
this.element.nativeElement.style.left = this.e.clientX + 'px';
}
}
if (this.clicked.onTopEdge) {
var currentHeight = Math.max(this.clicked.cy -
this.e.clientY +
this.clicked.h, this.minHeight);
if (currentHeight > this.minHeight) {
this.element.nativeElement.style.height = currentHeight + 'px';
this.element.nativeElement.style.top = this.e.clientY + 'px';
}
}
return;
}
}
onUp(ev) {
this.calc(ev);
this.clicked = null;
}
}
HTML snippet on which directive has been applied
<div class="box" *ngFor="let box of dropzone1" appDroppable (dragStart)="currentBox = box" appMovable>
{{ box.dis }}
<div class="side side-h" id="side-top" (dragStart)=(e) (dragMove)=(e) (dragEnd)=(e) appResizable></div>
<div class="side side-v" id="side-right" (click)="clcikme(e)" ></div>
<div class="side side-h" id="side-bottom" (click)="clcikme(e)"></div>
<div class="side side-v" id="side-left" (click)="clcikme(e)"></div>
</div>
In the codepen example for b
this.b = this.element.nativeElement.getBoundingClientRect();
the whole element has been taken which I'll also have to do, in my case I have the border on which the directive is there
I am attaching a working stackblitz the resizable directive is present in draggable folder and used in hello component In the stackblitz console logging of pointerdown, pointermove can also be seen.
https://stackblitz.com/edit/angular-pcpev1?file=src/app/hello.component.html
Error in console animate of undefined
Please refer to the codepen example from the comments.
Update
https://stackblitz.com/edit/angular-pcpev1?file=src%2Fapp%2Fhello.component.html