Skip to content

Commit

Permalink
feat: fix the padding issues
Browse files Browse the repository at this point in the history
  • Loading branch information
sheikalthaf authored Oct 25, 2023
1 parent eab4f4f commit 85ecb27
Show file tree
Hide file tree
Showing 17 changed files with 888 additions and 65 deletions.
3 changes: 0 additions & 3 deletions src/app/app.component.html

This file was deleted.

26 changes: 0 additions & 26 deletions src/app/app.component.scss

This file was deleted.

47 changes: 34 additions & 13 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import { Component, ViewChild, inject } from '@angular/core';
import { NgForOf } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { ContainerComponent } from './container.component';
import { FlowChildComponent } from './flow-child.component';
import { FlowComponent } from './flow.component';
import { FlowOptions } from './flow-interface';
import { FlowService } from './flow.service';
import { FlowChildComponent } from './flow/flow-child.component';
import { FlowComponent } from './flow/flow.component';
import { FlowOptions } from './flow/flow-interface';

@Component({
selector: 'app-root',
standalone: true,
imports: [
NgForOf,
RouterOutlet,
FlowComponent,
ContainerComponent,
FlowChildComponent,
],
imports: [NgForOf, RouterOutlet, FlowComponent, FlowChildComponent],
template: `
<button (click)="trigger()">Arrange</button>
Expand Down Expand Up @@ -54,7 +46,36 @@ import { FlowService } from './flow.service';
</app-flow>
</div>
`,
styleUrls: ['./app.component.scss'],
styles: [
`
.card {
display: flex;
align-items: center;
justify-content: center;
width: 180px;
height: 40px;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.3);
border-radius: 5px;
background-color: white;
}
.doting {
--scale: 2;
left: 318px;
top: 263px;
width: calc(5px + (5px * var(--scale)));
height: calc(5px + (5px * var(--scale)));
position: fixed;
background: blue;
z-index: 124;
pointer-events: none;
}
button {
@apply p-1;
}
`,
],
})
export class AppComponent {
title = 'angular-flow';
Expand Down
23 changes: 0 additions & 23 deletions src/app/container.component.ts

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
180 changes: 180 additions & 0 deletions src/app/flow/flow-child.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import { CommonModule } from '@angular/common';
import {
Component,
OnInit,
OnDestroy,
ViewChildren,
QueryList,
ElementRef,
Input,
NgZone,
OnChanges,
SimpleChanges,
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { Subject, Subscription } from 'rxjs';
import { FlowService } from './flow.service';
import { FlowOptions } from './flow-interface';

@Component({
standalone: true,
imports: [CommonModule],
selector: '[flowChild]',
template: `<ng-content></ng-content>
<div #dot class="dot dot-top"></div>
<div #dot class="dot dot-right"></div>
<div #dot class="dot dot-bottom"></div>
<div #dot class="dot dot-left"></div>`,
styles: [
`
.dot {
--dot-size: 10px;
--dot-half-size: -5px;
position: absolute;
width: var(--dot-size);
height: var(--dot-size);
background: red;
border-radius: 999px;
}
.dot-left {
top: calc(50% + var(--dot-half-size));
left: var(--dot-half-size);
}
.dot-right {
top: calc(50% + var(--dot-half-size));
right: var(--dot-half-size);
}
.dot-top {
left: 50%;
top: var(--dot-half-size);
}
.dot-bottom {
left: 50%;
bottom: var(--dot-half-size);
}
.invisible {
visibility: hidden;
}
`,
],
})
export class FlowChildComponent implements OnInit, OnChanges, OnDestroy {
private isDragging = false;
private offsetX = 0;
private offsetY = 0;

@ViewChildren('dot') dots: QueryList<ElementRef<HTMLDivElement>>;

@Input('flowChild') position: FlowOptions;

private positionChange = new Subject<FlowOptions>();
private mouseMoveSubscription: Subscription;

constructor(
public el: ElementRef<HTMLDivElement>,
private flow: FlowService,
private ngZone: NgZone
) {
this.el.nativeElement.style.position = 'absolute';
this.el.nativeElement.style.transformOrigin = '0, 0';
// track mouse move outside angular
this.ngZone.runOutsideAngular(() => {
this.flow.enableChildDragging.subscribe((x) => {
if (x) {
this.enableDragging();
} else {
this.disableDragging();
}
});
});

this.flow.layoutUpdated.pipe(takeUntilDestroyed()).subscribe((x) => {
this.position = this.flow.items.get(this.position.id) as FlowOptions;
this.positionChange.next(this.position);
});

this.positionChange.subscribe((x) => {
const { left, top } = this.flow.zRect;
if (!this.position) console.log(this.position);
this.updatePosition(this.position.x + left, this.position.y + top);
});
}

private onMouseUp = (event: MouseEvent) => {
event.stopPropagation();
this.isDragging = false;
this.flow.isChildDragging = false;
};

private onMouseDown = (event: MouseEvent) => {
event.stopPropagation();
this.isDragging = true;
this.flow.isChildDragging = true;
const rect = this.el.nativeElement.getBoundingClientRect();
this.offsetX = event.clientX - rect.x;
this.offsetY = event.clientY - rect.y;
};

private onMouseMove = (event: MouseEvent) => {
event.stopPropagation();
event.preventDefault();
if (this.isDragging) {
event.stopPropagation();
const zRect = this.flow.zRect;
const cx = event.clientX - zRect.left;
const cy = event.clientY - zRect.top;
const x =
Math.round(
(cx - this.flow.panX - this.offsetX) /
(this.flow.gridSize * this.flow.scale)
) * this.flow.gridSize;
const y =
Math.round(
(cy - this.flow.panY - this.offsetY) /
(this.flow.gridSize * this.flow.scale)
) * this.flow.gridSize;

this.position.x = x - zRect.left;
this.position.y = y - zRect.top;
this.positionChange.next(this.position);
this.flow.arrowsChange.next(this.position);
}
};

private enableDragging() {
this.mouseMoveSubscription = this.flow.onMouse.subscribe(this.onMouseMove);
// mouse up event
this.el.nativeElement.addEventListener('mouseup', this.onMouseUp);

// mouse down event
this.el.nativeElement.addEventListener('mousedown', this.onMouseDown);
}

private disableDragging() {
this.mouseMoveSubscription?.unsubscribe();
this.el.nativeElement.removeEventListener('mouseup', this.onMouseUp);
this.el.nativeElement.removeEventListener('mousedown', this.onMouseDown);
}

ngOnInit() {
this.updatePosition(this.position.x, this.position.y);
}

ngOnChanges(changes: SimpleChanges): void {
console.log(`ngOnChanges ${this.position.id}`, changes);
// if (changes['position']) {
// this.updatePosition(this.position.x, this.position.y);
// }
}

private updatePosition(x: number, y: number) {
this.el.nativeElement.style.transform = `translate(${x}px, ${y}px)`;
}

ngOnDestroy() {
this.disableDragging();
// remove the FlowOptions from the flow service
// this.flow.delete(this.position);
// console.log('ngOnDestroy', this.position.id);
}
}
6 changes: 6 additions & 0 deletions src/app/flow/flow-interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface FlowOptions {
x: number;
y: number;
id: string;
deps: string[];
}
File renamed without changes.
Loading

0 comments on commit 85ecb27

Please sign in to comment.