Skip to content

Commit

Permalink
fix: if the ctrl + mouse wheel lets scale the netzgrafik or multi-sel…
Browse files Browse the repository at this point in the history
…ected nodes (local scale) (#376)

* fix: import 3rd party performance

* fix: ctrl + mouse wheel -> scale netzgrafik or multi-select node and scale

* fix: ctrl + mouse wheel -> scale netzgrafik or multi-select node and scale
  • Loading branch information
aiAdrian authored Dec 11, 2024
1 parent 236786f commit de55afe
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 14 deletions.
75 changes: 75 additions & 0 deletions src/app/view/editor-main-view/data-views/editor.view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,11 @@ export class EditorView implements SVGMouseControllerObserver {
this.trainrunSectionPreviewLineView.stopPreviewLine();
}


onScaleNetzgrafik(factor: number, scaleCenter: Vec2D) {
this.scaleNetzgrafikArea(factor, scaleCenter);
}

zoomFactorChanged(newZoomFactor: number) {
this.controller.zoomFactorChanged(newZoomFactor);
this.viewportCullService.onViewportChangeUpdateRendering(true);
Expand Down Expand Up @@ -687,4 +692,74 @@ export class EditorView implements SVGMouseControllerObserver {
el.classed("ShowCellCursor", false);
}
}


private scaleFullNetzgrafikArea(factor: number, zoomCenter: Vec2D) {
const vp = this.uiInteractionService.getViewboxProperties(EditorView.svgName);
const scaleCenterCoordinates = new Vec2D(
vp.panZoomLeft + zoomCenter.getX() * vp.panZoomWidth,
vp.panZoomTop + zoomCenter.getY() * vp.panZoomHeight,
);

// get the node under the mouse cursos and update the scaleCenter
const focalNode = this.nodeService.getNodes().find((n) =>
scaleCenterCoordinates.getX() > n.getPositionX() && scaleCenterCoordinates.getX() < (n.getPositionX() + n.getNodeWidth()) &&
scaleCenterCoordinates.getY() > n.getPositionY() && scaleCenterCoordinates.getY() < (n.getPositionY() + n.getNodeHeight())
);

this.nodeService.getNodes().forEach((n, index) => {
let newPos = new Vec2D(
(n.getPositionX() - scaleCenterCoordinates.getX()) * factor + scaleCenterCoordinates.getX(),
(n.getPositionY() - scaleCenterCoordinates.getY()) * factor + scaleCenterCoordinates.getY()
);

if (focalNode?.getId() === n.getId()) {
const delta = Vec2D.sub(newPos, new Vec2D(focalNode.getPositionX(), focalNode.getPositionY(),));
newPos = Vec2D.sub(newPos, delta);
}
n.setPosition(newPos.getX(), newPos.getY());
});
}

private scaleNetzgrafikSelectedNodesArea(factor: number, nodes: Node[]) {
/*
* if more than one node is selected (multi-selected nodes) transform the nodes with center of
* mass
*/
let cx = 0;
let cy = 0;
nodes.forEach(n => {
cx += n.getPositionX() + n.getNodeWidth() / 2.0;
cy += n.getPositionY() + n.getNodeHeight() / 2.0;
});
cx /= nodes.length;
cy /= nodes.length;
const v = Vec2D.normalize(new Vec2D(cx, cy));
nodes.forEach((n, index) => {
const posX = (n.getPositionX() + n.getNodeWidth() / 2.0 - cx) * factor + cx - n.getNodeWidth() / 2.0;
const posY = (n.getPositionY() + n.getNodeHeight() / 2.0 - cy) * factor + cy - n.getNodeHeight() / 2.0;
n.setPosition(posX, posY);
});
}

private scaleNetzgrafikArea(factor: number, zoomCenter: Vec2D) {
const nodes: Node[] = this.nodeService.getSelectedNodes();

if (nodes.length < 2) {
this.scaleFullNetzgrafikArea(factor, zoomCenter);
} else {
this.scaleNetzgrafikSelectedNodesArea(factor, nodes);
}

this.trainrunSectionService.getTrainrunSections().forEach(ts => {
ts.routeEdgeAndPlaceText();
ts.getSourceNode().updateTransitionsAndConnections();
});

this.nodeService.initPortOrdering();

this.viewportCullService.onViewportChangeUpdateRendering(true);
}


}
26 changes: 16 additions & 10 deletions src/app/view/util/svg.mouse.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
SVGMouseController,
SVGMouseControllerObserver,
} from "./svg.mouse.controller";
import {SVGMouseController, SVGMouseControllerObserver,} from "./svg.mouse.controller";
import {Vec2D} from "../../utils/vec2D";
import {ViewboxProperties} from "../../services/ui/ui.interaction.service";

Expand All @@ -10,17 +7,26 @@ class DummySVGMouseControllerObserver implements SVGMouseControllerObserver {
return true;
}

onGraphContainerMouseup(mousePosition: Vec2D, onPaning: boolean) {}
onGraphContainerMouseup(mousePosition: Vec2D, onPaning: boolean) {
}

zoomFactorChanged(newZoomFactor: number) {
}

zoomFactorChanged(newZoomFactor: number) {}
onViewboxChanged(viewboxProperties: ViewboxProperties) {
}

onViewboxChanged(viewboxProperties: ViewboxProperties) {}
onStartMultiSelect() {
}

onStartMultiSelect() {}
updateMultiSelect(topLeft: Vec2D, bottomRight: Vec2D) {
}

updateMultiSelect(topLeft: Vec2D, bottomRight: Vec2D) {}
onEndMultiSelect() {
}

onEndMultiSelect() {}
onScaleNetzgrafik(factor: number, scaleCenter: Vec2D) {
}
}

describe("general view functions", () => {
Expand Down
32 changes: 28 additions & 4 deletions src/app/view/util/svg.mouse.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export interface SVGMouseControllerObserver {
updateMultiSelect(topLeft: Vec2D, bottomRight: Vec2D);

onEndMultiSelect();

onScaleNetzgrafik(factor: number, scaleCenter: Vec2D);
}

export class SVGMouseController {
Expand All @@ -36,7 +38,8 @@ export class SVGMouseController {
constructor(
private svgName: string,
private svgMouseControllerObserver: SVGMouseControllerObserver,
) {}
) {
}

init(viewboxProperties: ViewboxProperties) {
this.viewboxProperties = viewboxProperties;
Expand Down Expand Up @@ -100,6 +103,15 @@ export class SVGMouseController {
);
}


scaleIn(scaleCenter: Vec2D) {
this.svgMouseControllerObserver.onScaleNetzgrafik(1.125, scaleCenter);
}

scaleOut(scaleCenter: Vec2D) {
this.svgMouseControllerObserver.onScaleNetzgrafik(1.0 / 1.125, scaleCenter);
}

zoomIn(zoomCenter: Vec2D, factor = 1.0) {
if (this.viewboxIsFixed) {
return;
Expand Down Expand Up @@ -312,11 +324,23 @@ export class SVGMouseController {
d3.event.offsetX / this.viewboxProperties.origWidth,
d3.event.offsetY / this.viewboxProperties.origHeight,
);
if (d3.event.deltaY > 0) {
this.zoomOut(zoomCenter);

if (!d3.event.ctrlKey) {
// mouse wheel
if (d3.event.deltaY > 0) {
this.zoomOut(zoomCenter);
} else {
this.zoomIn(zoomCenter);
}
} else {
this.zoomIn(zoomCenter);
// ctrl and mouse wheel
if (d3.event.deltaY > 0) {
this.scaleOut(zoomCenter);
} else {
this.scaleIn(zoomCenter);
}
}

d3.event.preventDefault();
d3.event.stopPropagation();
}
Expand Down

0 comments on commit de55afe

Please sign in to comment.