Skip to content

Commit

Permalink
Merge pull request #12 from joel-wenzel/issue/10
Browse files Browse the repository at this point in the history
Issue/10 - Canvas Zoom Support
  • Loading branch information
joel-wenzel authored Jun 29, 2021
2 parents 9e2811e + 3c7ecf2 commit 6acfba1
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 62 deletions.
14 changes: 14 additions & 0 deletions projects/ng-flowchart/src/lib/model/flow.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ export namespace NgFlowchart {

/** Should the canvas be centered when a resize is detected? */
centerOnResize?: boolean = true;

/** Canvas zoom options. Defaults to mouse wheel zoom */
zoom?: {
mode: 'WHEEL' | 'MANUAL' | 'DISABLED'
defaultStep: number
} = {
mode: 'WHEEL',
defaultStep: .1
}
}

export type DropEvent = {
Expand Down Expand Up @@ -169,6 +178,11 @@ export namespace NgFlowchart {
* Called after the canvas completes a re-render
*/
afterRender?: () => void

/**
* Called after the canvas has been scaled
*/
afterScale?: (newScale: number) => void
};
}

Expand Down
76 changes: 56 additions & 20 deletions projects/ng-flowchart/src/lib/ng-flowchart-canvas.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ import { StepManagerService } from './services/step-manager.service';
CanvasRendererService
]
})
export class NgFlowchartCanvasDirective implements OnInit, OnDestroy, AfterViewInit {
export class NgFlowchartCanvasDirective implements OnInit, OnDestroy, AfterViewInit {

@HostListener('drop', ['$event'])
protected onDrop(event: DragEvent) {
if (this._disabled) { return; }

// its possible multiple canvases exist so make sure we only move/drop on the closest one
const closestCanvasId = (event.target as HTMLElement).closest('.ngflowchart-canvas-content')?.id
if(this._id !== closestCanvasId) {
if (this._id !== closestCanvasId) {
return;
}

const type = event.dataTransfer.getData('type');
if ('FROM_CANVAS' == type) {
this.canvas.moveStep(event, event.dataTransfer.getData('id'));
Expand All @@ -54,7 +54,13 @@ export class NgFlowchartCanvasDirective implements OnInit, OnDestroy, AfterViewI
if (this._options.centerOnResize) {
this.canvas.reRender(true);
}
}

@HostListener('wheel', ['$event'])
protected onZoom(event) {
if (this._options.zoom.mode === 'WHEEL') {
this.adjustWheelScale(event)
}
}

@Input('ngFlowchartCallbacks')
Expand All @@ -74,26 +80,30 @@ export class NgFlowchartCanvasDirective implements OnInit, OnDestroy, AfterViewI
@HostBinding('attr.disabled')
set disabled(val: boolean) {
this._disabled = val !== false;
if(this.canvas) {
if (this.canvas) {
this.canvas._disabled = this._disabled;
}
}

get disabled() {
return this._disabled;
}

_disabled: boolean = false;
_id: string = null
private _disabled: boolean = false;
private _id: string = null
private canvasContent: HTMLElement;

constructor(
protected canvasEle: ElementRef<HTMLElement>,
private viewContainer: ViewContainerRef,
private canvas: NgFlowchartCanvasService,
private optionService: OptionsService
) {

this.canvasEle.nativeElement.classList.add(CONSTANTS.CANVAS_CLASS);
this._id = this.createCanvasContent(this.viewContainer);

this.canvasContent = this.createCanvasContent(this.viewContainer);
this._id = this.canvasContent.id

}

ngOnInit() {
Expand All @@ -103,35 +113,31 @@ export class NgFlowchartCanvasDirective implements OnInit, OnDestroy, AfterViewI
}

this.canvas._disabled = this._disabled;

}

ngAfterViewInit() {

}

ngOnDestroy() {
for(let i = 0 ; i < this.viewContainer.length; i++){

for (let i = 0; i < this.viewContainer.length; i++) {
this.viewContainer.remove(i)
}
this.canvasEle.nativeElement.remove()
this.viewContainer.element.nativeElement.remove()
// this.canvas = undefined
// this.canvasEle = undefined
// this.optionService = undefined
this.viewContainer = undefined
}

private createCanvasContent(viewContainer: ViewContainerRef): string {
private createCanvasContent(viewContainer: ViewContainerRef): HTMLElement {
const canvasId = 'c' + Date.now();

let canvasEle = viewContainer.element.nativeElement as HTMLElement;
let canvasContent = document.createElement('div');
canvasContent.id = canvasId;
canvasContent.classList.add(CONSTANTS.CANVAS_CONTENT_CLASS);
canvasEle.appendChild(canvasContent);
return canvasId
return canvasContent
}

/**
Expand All @@ -140,4 +146,34 @@ export class NgFlowchartCanvasDirective implements OnInit, OnDestroy, AfterViewI
public getFlow() {
return new NgFlowchart.Flow(this.canvas);
}

public scaleDown() {
this.canvas.scaleDown()
}

public scaleUp() {
this.canvas.scaleUp()
}

public setScale(scaleValue: number) {

const scaleVal = Math.max(0, scaleValue)
this.canvas.setScale(scaleVal)
}

private adjustWheelScale(event) {

if (this.canvas.flow.hasRoot()) {
event.preventDefault();
// scale down / zoom out
if (event.deltaY > 0) {
this.scaleDown()
}
// scale up / zoom in
else if (event.deltaY < 0) {
this.scaleUp()
}

}
};
}
43 changes: 37 additions & 6 deletions projects/ng-flowchart/src/lib/ng-flowchart-canvas.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { CanvasRendererService } from './services/canvas-renderer.service';
import { DropDataService as DragService } from './services/dropdata.service';
import { OptionsService } from './services/options.service';
import { StepManagerService } from './services/step-manager.service';
import {first} from 'rxjs/operators'
import { first } from 'rxjs/operators'

export class CanvasFlow {
rootStep: NgFlowchartStepComponent;

// steps from this canvas only
private _steps: NgFlowchartStepComponent[] = [];

hasRoot() {
return !!this.rootStep;
}
Expand All @@ -22,7 +22,7 @@ export class CanvasFlow {
}

removeStep(step: NgFlowchartStepComponent) {

let index = this._steps.findIndex(ele => ele.id == step.id);
if (index >= 0) {
this._steps.splice(index, 1);
Expand Down Expand Up @@ -65,7 +65,7 @@ export class NgFlowchartCanvasService {
private renderer: CanvasRendererService,
private stepmanager: StepManagerService
) {


}

Expand Down Expand Up @@ -116,7 +116,7 @@ export class NgFlowchartCanvasService {

}



public async onDrop(drag: DragEvent) {
this.renderer.clearAllSnapIndicators(this.flow.steps);
Expand Down Expand Up @@ -176,7 +176,7 @@ export class NgFlowchartCanvasService {
})
}

public createStep(pending: NgFlowchart.PendingStep): Promise<ComponentRef<NgFlowchartStepComponent>> {
public createStep(pending: NgFlowchart.PendingStep): Promise<ComponentRef<NgFlowchartStepComponent>> {
let componentRef: ComponentRef<NgFlowchartStepComponent>;

componentRef = this.stepmanager.create(pending, this);
Expand All @@ -189,6 +189,37 @@ export class NgFlowchartCanvasService {
})
}

public resetScale() {
if(this.options.options.zoom.mode === 'DISABLED') {
return
}
this.renderer.resetScale(this.flow)
}

public scaleUp(step?: number) {
if(this.options.options.zoom.mode === 'DISABLED') {
return
}
this.renderer.scaleUp(this.flow, step);

}

public scaleDown(step?: number) {
if(this.options.options.zoom.mode === 'DISABLED') {
return
}
this.renderer.scaleDown(this.flow, step);

}

public setScale(scaleValue: number) {
if(this.options.options.zoom.mode === 'DISABLED') {
return
}
this.renderer.setScale(this.flow, scaleValue)
}


addChildStep(componentRef: ComponentRef<NgFlowchartStepComponent>, dropTarget: NgFlowchart.DropTarget) {
this.addToCanvas(componentRef);
this.addStepToFlow(componentRef.instance, dropTarget);
Expand Down
Loading

0 comments on commit 6acfba1

Please sign in to comment.