Ability to detach notes. Generic "window" component since I'm now at 3 windows and it is getting cumbersome duplicating all that code all over the place.
parent
7c3e739f8d
commit
5c2d03272f
@ -0,0 +1,15 @@
|
|||||||
|
<ng-container *ngIf="init">
|
||||||
|
<ng-container *ngIf="rect">
|
||||||
|
<div class="target" [style.transform]="transform()" [style.width]="rect.width + 'px'"
|
||||||
|
[style.height]="rect.height + 'px'"
|
||||||
|
[style.background-color]="backgroundColor ? backgroundColor : 'rgba(0, 0, 0, 0.1)'" #targetRef>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ngx-moveable #moveable [target]="targetRef" [draggable]="configurable" [resizable]="configurable"
|
||||||
|
(drag)="onDrag($event)" (resize)="onResize($event)" (dragEnd)="onDragEnd($event)"
|
||||||
|
(resizeEnd)="onResizeEnd($event)" [bounds]="bounds" [snappable]="true"
|
||||||
|
[style.visibility]="configurable ? 'visible' : 'hidden'">
|
||||||
|
</ngx-moveable>
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
@ -0,0 +1,9 @@
|
|||||||
|
:host {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.target {
|
||||||
|
position: absolute;
|
||||||
|
min-width: 50px;
|
||||||
|
min-height: 50px;
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DraggableWindowComponent } from './draggable-window.component';
|
||||||
|
|
||||||
|
describe('DraggableWindowComponent', () => {
|
||||||
|
let component: DraggableWindowComponent;
|
||||||
|
let fixture: ComponentFixture<DraggableWindowComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [DraggableWindowComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(DraggableWindowComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,88 @@
|
|||||||
|
import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, Input, NgZone, OnInit, Output, ViewChild } from '@angular/core';
|
||||||
|
import { Rect } from '../_models/generated/Rect';
|
||||||
|
import { NgxMoveableComponent, NgxMoveableModule, OnDrag, OnDragEnd, OnResize, OnResizeEnd } from 'ngx-moveable';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-draggable-window',
|
||||||
|
templateUrl: './draggable-window.component.html',
|
||||||
|
styleUrls: ['./draggable-window.component.scss'],
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule, NgxMoveableModule]
|
||||||
|
|
||||||
|
})
|
||||||
|
export class DraggableWindowComponent implements AfterViewInit {
|
||||||
|
rect?: Rect;
|
||||||
|
bounds: any = { "left": 0, "top": 0, "right": 0, "bottom": 0, "position": "css" };
|
||||||
|
@Input() public backgroundColor: string = "rgba(0, 0, 0, 0.1)";
|
||||||
|
@Input() public configurable: boolean = true;
|
||||||
|
@Input() public initialRect?: Rect;
|
||||||
|
@Output() savedRect: EventEmitter<Rect> = new EventEmitter();
|
||||||
|
@ViewChild("moveable") moveable?: NgxMoveableComponent;
|
||||||
|
init = false;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private cdr: ChangeDetectorRef, private zone: NgZone) {
|
||||||
|
window.addEventListener("resize", () => {
|
||||||
|
this.zone.run(() => {
|
||||||
|
this.windowInitHandler()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
windowInitHandler() {
|
||||||
|
if (window.innerWidth > 0) {
|
||||||
|
const cfgRect = this.initialRect || { x: 0, y: 0, width: 0.1, height: 0.1 };
|
||||||
|
|
||||||
|
this.rect = {
|
||||||
|
x: cfgRect.x * window.innerWidth,
|
||||||
|
y: cfgRect.y * window.innerHeight,
|
||||||
|
width: cfgRect.width * window.innerWidth,
|
||||||
|
height: cfgRect.height * window.innerHeight,
|
||||||
|
}
|
||||||
|
|
||||||
|
this.moveable?.updateRect();
|
||||||
|
|
||||||
|
setTimeout(() => this.cdr.detectChanges(), 0);
|
||||||
|
this.init = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
this.windowInitHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
transform() {
|
||||||
|
return `translate(${this.rect!.x}px, ${this.rect!.y}px)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
onDrag(e: OnDrag) {
|
||||||
|
this.rect!.x = e.translate[0];
|
||||||
|
this.rect!.y = e.translate[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
onDragEnd(_e: OnDragEnd) {
|
||||||
|
this.saveRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
onResize(e: OnResize) {
|
||||||
|
this.rect!.width = e.width;
|
||||||
|
this.rect!.height = e.height;
|
||||||
|
this.onDrag(e.drag);
|
||||||
|
}
|
||||||
|
|
||||||
|
onResizeEnd(_e: OnResizeEnd) {
|
||||||
|
this.saveRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
saveRect() {
|
||||||
|
if (this.rect) {
|
||||||
|
this.savedRect.emit({
|
||||||
|
x: this.rect.x / window.innerWidth,
|
||||||
|
y: this.rect.y / window.innerHeight,
|
||||||
|
width: this.rect.width / window.innerWidth,
|
||||||
|
height: this.rect.height / window.innerHeight,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue