From eafdb8ae3faacf83c8027bcad493af37fc161dea Mon Sep 17 00:00:00 2001 From: rhenck <richard.henck@iqb.hu-berlin.de> Date: Mon, 19 Jul 2021 16:40:38 +0200 Subject: [PATCH] [editor] Add drag resize functionality to canvas elements Somewhat messy because of more nested droplists and a handler triggering every pixel. But the best I can do for now. May revisit later. --- .../canvas/canvas-drag-overlay.component.ts | 60 ++++++++++++++----- projects/editor/src/styles.css | 3 + 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/projects/editor/src/app/components/unit-view/page-view/canvas/canvas-drag-overlay.component.ts b/projects/editor/src/app/components/unit-view/page-view/canvas/canvas-drag-overlay.component.ts index f3d93d8b1..9acbd36bb 100644 --- a/projects/editor/src/app/components/unit-view/page-view/canvas/canvas-drag-overlay.component.ts +++ b/projects/editor/src/app/components/unit-view/page-view/canvas/canvas-drag-overlay.component.ts @@ -1,32 +1,48 @@ import { Component, OnInit, Input, Output, EventEmitter, ComponentFactoryResolver, ViewChild, ViewContainerRef } from '@angular/core'; +import { CdkDragMove } from '@angular/cdk/drag-drop'; import { UnitUIElement } from '../../../../../../../common/unit'; -import { FormElementComponent } from '../../../../../../../common/form-element-component.directive'; import * as ComponentUtils from '../../../../../../../common/component-utils'; +import { UnitService } from '../../../../unit.service'; @Component({ selector: 'app-canvas-drag-overlay', template: ` -<!-- Needs extra div because styling can interfere with drag and drop--> - <div cdkDrag [cdkDragData]="this.element" - [cdkDragDisabled]="!_selected" + <!-- Needs extra div because styling can interfere with drag and drop--> + <div class="draggable-element" [class.draggable-element-selected]="selected" + cdkDrag [cdkDragData]="this.element" [cdkDragDisabled]="!selected" (click)="click($event)"> - <div [ngStyle]="style" - [style.position]="'absolute'" - [style.border]="_selected ? '2px solid' : ''" + <div [style.position]="'absolute'" + [style.border]="selected ? '2px solid' : ''" [style.width.px]="element.width" [style.height.px]="element.height" [style.left.px]="element.xPosition" [style.top.px]="element.yPosition" [style.z-index]="element.zIndex"> -<!-- <button cdkDrag cdkDragHandle></button>--> + <!-- Element only for resizing --> + <!-- Extra droplist is needed to keep parent component droplist from handling the drop event. --> + <!-- Also for cursor styling. --> + <div cdkDropList class="test" *ngIf="selected" + [style.width.%]="100" + [style.height.%]="100"> + <div class="resizeHandle" + cdkDrag (cdkDragStarted)="dragStart()" (cdkDragMoved)="resizeElement($event)" + [style.right.px]="-1" [style.bottom.px]="-7"> + <mat-icon>aspect_ratio</mat-icon> + <div *cdkDragPlaceholder></div> + </div> + </div> <ng-template #elementContainer></ng-template> </div> </div> - `, + `, styles: [ - 'div {position: absolute}' + 'div {position: absolute}', + '.draggable-element-selected {cursor: grab}', + '.draggable-element-selected:active {cursor: grabbing}', + '.draggable-element-selected .resizeHandle {cursor: nwse-resize}', + '.test.cdk-drop-list-dragging {cursor: nwse-resize}' ] }) export class CanvasDragOverlayComponent implements OnInit { @@ -36,16 +52,18 @@ export class CanvasDragOverlayComponent implements OnInit { multiSelect: boolean }>(); @ViewChild('elementContainer', { read: ViewContainerRef, static: true }) private elementContainer!: ViewContainerRef; - private childComponent!: FormElementComponent; - _selected = false; - style: Record<string, string> = {}; - constructor(private componentFactoryResolver: ComponentFactoryResolver) { } + selected = false; + private oldX: number = 0; + private oldY: number = 0; + + constructor(private unitService: UnitService, private componentFactoryResolver: ComponentFactoryResolver) { } ngOnInit(): void { const componentFactory = ComponentUtils.getComponentFactory(this.element.type, this.componentFactoryResolver); - this.childComponent = this.elementContainer.createComponent(componentFactory).instance; - this.childComponent.elementModel = this.element; + const childComponent = this.elementContainer.createComponent(componentFactory); + childComponent.instance.elementModel = this.element; + childComponent.location.nativeElement.firstChild.style.cursor = 'inherit'; } set selected(newValue: boolean) { @@ -63,4 +81,14 @@ export class CanvasDragOverlayComponent implements OnInit { }); } } + + dragStart(): void { + this.oldX = this.element.width; + this.oldY = this.element.height; + } + + resizeElement(event: CdkDragMove): void { + this.unitService.updateSelectedElementProperty('width', Math.max(this.oldX + event.distance.x, 0)); + this.unitService.updateSelectedElementProperty('height', Math.max(this.oldY + event.distance.y, 0)); + } } diff --git a/projects/editor/src/styles.css b/projects/editor/src/styles.css index 99d511720..49bf2fb7e 100644 --- a/projects/editor/src/styles.css +++ b/projects/editor/src/styles.css @@ -7,3 +7,6 @@ body { .snackbar-warning {border: 3px double #ff4d4d} .snackbar-error {background-color: #ff4d4d} + + +.cdk-drop-list-dragging {cursor: grabbing} -- GitLab