mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-19 04:57:51 +00:00
Support canvas transformation when dragged, Fixes: #96
This commit is contained in:
parent
01f2518323
commit
74e60bd8d0
@ -84,9 +84,9 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.graphContext = new Context(true);
|
||||
|
||||
if (this.windowFullSize) {
|
||||
this.graphContext.setSize(this.getSize());
|
||||
this.graphContext.size = this.getSize();
|
||||
} else {
|
||||
this.graphContext.setSize(new Size(this.width, this.height));
|
||||
this.graphContext.size = new Size(this.width, this.height);
|
||||
}
|
||||
|
||||
this.graphLayout = new GraphLayout();
|
||||
@ -113,19 +113,14 @@ export class MapComponent implements OnInit, OnChanges, OnDestroy {
|
||||
}
|
||||
|
||||
private changeLayout() {
|
||||
if (this.windowFullSize) {
|
||||
if (this.parentNativeElement != null) {
|
||||
this.graphContext.setSize(this.getSize());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (this.parentNativeElement != null) {
|
||||
this.graphContext.size = this.getSize();
|
||||
}
|
||||
|
||||
if (this.graphContext != null) {
|
||||
this.svg
|
||||
.attr('width', this.graphContext.getSize().width)
|
||||
.attr('height', this.graphContext.getSize().height);
|
||||
.attr('width', this.graphContext.size.width)
|
||||
.attr('height', this.graphContext.size.height);
|
||||
}
|
||||
|
||||
this.graphLayout.setNodes(this.nodes);
|
||||
|
@ -1,25 +1,27 @@
|
||||
import {Size} from "./size";
|
||||
import {Point} from "./point";
|
||||
|
||||
export class Transformation {
|
||||
constructor(
|
||||
public x: number,
|
||||
public y: number,
|
||||
public k: number
|
||||
) {}
|
||||
}
|
||||
|
||||
|
||||
export class Context {
|
||||
private size: Size;
|
||||
public transformation: Transformation;
|
||||
public size: Size;
|
||||
|
||||
constructor(private centerZeroZeroPoint = false) {
|
||||
constructor(public centerZeroZeroPoint = true) {
|
||||
this.size = new Size(0, 0);
|
||||
}
|
||||
|
||||
public getSize(): Size {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public setSize(size: Size): void {
|
||||
this.size = size;
|
||||
this.transformation = new Transformation(0, 0, 1);
|
||||
}
|
||||
|
||||
public getZeroZeroTransformationPoint() {
|
||||
if (this.centerZeroZeroPoint) {
|
||||
return new Point(this.getSize().width / 2., this.getSize().height / 2.);
|
||||
return new Point(this.size.width / 2., this.size.height / 2.);
|
||||
}
|
||||
return new Point(0, 0);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import { Context } from "../models/context";
|
||||
import { SVGSelection } from "../models/types";
|
||||
import { MovingTool } from "./moving-tool";
|
||||
import { TestSVGCanvas } from "../../testing";
|
||||
import { Size } from "../models/size";
|
||||
|
||||
|
||||
describe('MovingTool', () => {
|
||||
@ -47,8 +48,42 @@ describe('MovingTool', () => {
|
||||
it('canvas should transformed', () => {
|
||||
expect(svg.canvas.attr('transform')).toEqual('translate(100, 100) scale(1)');
|
||||
});
|
||||
|
||||
it('context transformation should be updated', () => {
|
||||
expect(context.transformation.x).toEqual(100);
|
||||
expect(context.transformation.y).toEqual(100);
|
||||
expect(context.transformation.k).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('MovingTool can move canvas with ZeroZeroTransformationPoint', () => {
|
||||
beforeEach(() => {
|
||||
context.centerZeroZeroPoint = true;
|
||||
context.size = new Size(1000, 1000);
|
||||
|
||||
svg.svg.node().dispatchEvent(
|
||||
new MouseEvent('mousedown', {
|
||||
clientX: 100, clientY: 100, relatedTarget: svg.svg.node(),
|
||||
screenY: 1024, screenX: 1024, view: window
|
||||
})
|
||||
);
|
||||
|
||||
window.dispatchEvent(new MouseEvent('mousemove', {clientX: 200, clientY: 200}));
|
||||
window.dispatchEvent(new MouseEvent('mouseup', {clientX: 200, clientY: 200, view: window}));
|
||||
});
|
||||
|
||||
it('canvas should transformed', () => {
|
||||
expect(svg.canvas.attr('transform')).toEqual('translate(600, 600) scale(1)');
|
||||
});
|
||||
|
||||
it('context transformation should be updated', () => {
|
||||
expect(context.transformation.x).toEqual(100);
|
||||
expect(context.transformation.y).toEqual(100);
|
||||
expect(context.transformation.k).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('MovingTool can be deactivated', () => {
|
||||
beforeEach(() => {
|
||||
tool.deactivate();
|
||||
|
@ -1,8 +1,10 @@
|
||||
import {SVGSelection} from "../models/types";
|
||||
import {Context} from "../models/context";
|
||||
import {D3ZoomEvent, zoom, ZoomBehavior} from "d3-zoom";
|
||||
import { D3ZoomEvent, zoom, ZoomBehavior} from "d3-zoom";
|
||||
import { event } from "d3-selection";
|
||||
|
||||
import { SVGSelection} from "../models/types";
|
||||
import { Context} from "../models/context";
|
||||
|
||||
|
||||
export class MovingTool {
|
||||
private selection: SVGSelection;
|
||||
private context: Context;
|
||||
@ -32,9 +34,17 @@ export class MovingTool {
|
||||
const canvas = self.selection.select<SVGGElement>("g.canvas");
|
||||
const e: D3ZoomEvent<SVGSVGElement, any> = event;
|
||||
canvas.attr(
|
||||
'transform',
|
||||
`translate(${self.context.getSize().width / 2 + e.transform.x}, ` +
|
||||
`${self.context.getSize().height / 2 + e.transform.y}) scale(${e.transform.k})`);
|
||||
'transform',
|
||||
() => {
|
||||
self.context.transformation.x = e.transform.x;
|
||||
self.context.transformation.y = e.transform.y;
|
||||
self.context.transformation.k = e.transform.k;
|
||||
|
||||
const xTrans = self.context.getZeroZeroTransformationPoint().x + self.context.transformation.x;
|
||||
const yTrans = self.context.getZeroZeroTransformationPoint().y + self.context.transformation.y;
|
||||
const kTrans = self.context.transformation.k;
|
||||
return `translate(${xTrans}, ${yTrans}) scale(${kTrans})`;
|
||||
});
|
||||
};
|
||||
|
||||
this.zoom.on('zoom', onZoom);
|
||||
|
@ -113,4 +113,16 @@ describe('SelectionTool', () => {
|
||||
expect(path_selection.attr('visibility')).toEqual('hidden');
|
||||
});
|
||||
});
|
||||
|
||||
describe('SelectionTool correctly transform points with context transformation', () => {
|
||||
beforeEach(() => {
|
||||
context.transformation.x = 100;
|
||||
context.transformation.y = 100;
|
||||
svg.svg.node().dispatchEvent(new MouseEvent('mousedown', {clientX: 100, clientY: 100}));
|
||||
});
|
||||
|
||||
it('path should have d adjusted for transformation', () => {
|
||||
expect(path_selection.attr('d')).toEqual('M-5,-14 l0,0 l0,0 l0,0z');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -105,7 +105,10 @@ export class SelectionTool {
|
||||
|
||||
private transformation(point) {
|
||||
const transformation_point = this.context.getZeroZeroTransformationPoint();
|
||||
return [point[0] - transformation_point.x, point[1] - transformation_point.y];
|
||||
return [
|
||||
point[0] - transformation_point.x - this.context.transformation.x,
|
||||
point[1] - transformation_point.y - this.context.transformation.y
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,8 +27,6 @@ export class GraphLayout implements Widget {
|
||||
private movingTool: MovingTool;
|
||||
private layersWidget: LayersWidget;
|
||||
|
||||
private centerZeroZeroPoint = true;
|
||||
|
||||
constructor() {
|
||||
this.linksWidget = new LinksWidget();
|
||||
this.nodesWidget = new NodesWidget();
|
||||
@ -89,14 +87,19 @@ export class GraphLayout implements Widget {
|
||||
.data([context]);
|
||||
|
||||
const canvasEnter = canvas.enter()
|
||||
.append<SVGGElement>('g')
|
||||
.attr('class', 'canvas');
|
||||
.append<SVGGElement>('g')
|
||||
.attr('class', 'canvas');
|
||||
|
||||
if (this.centerZeroZeroPoint) {
|
||||
canvas.attr(
|
||||
'transform',
|
||||
(ctx: Context) => `translate(${ctx.getSize().width / 2}, ${ctx.getSize().height / 2})`);
|
||||
}
|
||||
canvas
|
||||
.merge(canvasEnter)
|
||||
.attr(
|
||||
'transform',
|
||||
(ctx: Context) => {
|
||||
const xTrans = ctx.getZeroZeroTransformationPoint().x + ctx.transformation.x;
|
||||
const yTrans = ctx.getZeroZeroTransformationPoint().y + ctx.transformation.y;
|
||||
const kTrans = ctx.transformation.k;
|
||||
return `translate(${xTrans}, ${yTrans}) scale(${kTrans})`;
|
||||
});
|
||||
|
||||
const layersManager = new LayersManager();
|
||||
layersManager.setNodes(this.nodes);
|
||||
|
Loading…
Reference in New Issue
Block a user