Skip to content

Commit 81c6f91

Browse files
AarebeccaSloth9527wangyun
authored
fix: correct the point after canvas rotation (#7235) (#7236)
Co-authored-by: JK <[email protected]> Co-authored-by: wangyun <[email protected]>
1 parent a476eff commit 81c6f91

File tree

4 files changed

+103
-0
lines changed

4 files changed

+103
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import type { Graph } from '@/src';
2+
import { CommonEvent } from '@/src';
3+
import { bugDragRotatedCanvas } from '@@/demos';
4+
import { createDemoGraph, dispatchCanvasEvent } from '@@/utils';
5+
6+
describe('behavior drag rotated canvas', () => {
7+
let graph: Graph;
8+
9+
beforeAll(async () => {
10+
graph = await createDemoGraph(bugDragRotatedCanvas, { animation: false });
11+
});
12+
13+
afterAll(() => {
14+
graph.destroy();
15+
});
16+
17+
it('drag 30 rotated canvas', async () => {
18+
await graph.rotateTo(30);
19+
const [x, y] = graph.getPosition();
20+
21+
dispatchCanvasEvent(graph, CommonEvent.DRAG_START, { targetType: 'canvas' });
22+
dispatchCanvasEvent(graph, CommonEvent.DRAG, { movement: { x: 10, y: 10 }, targetType: 'canvas' });
23+
dispatchCanvasEvent(graph, CommonEvent.DRAG_END);
24+
25+
expect(graph.getRotation()).toBe(30);
26+
expect(graph.getPosition()).toBeCloseTo([x + 3.66, y + 13.66]);
27+
});
28+
29+
it('drag 90 rotated canvas', async () => {
30+
await graph.rotateTo(90);
31+
const [x, y] = graph.getPosition();
32+
33+
dispatchCanvasEvent(graph, CommonEvent.DRAG_START, { targetType: 'canvas' });
34+
dispatchCanvasEvent(graph, CommonEvent.DRAG, { movement: { x: 10, y: 20 }, targetType: 'canvas' });
35+
dispatchCanvasEvent(graph, CommonEvent.DRAG_END);
36+
37+
expect(graph.getRotation()).toBe(90);
38+
expect(graph.getPosition()).toBeCloseTo([x - 20, y + 10]);
39+
});
40+
41+
it('drag 180 rotated canvas', async () => {
42+
await graph.rotateTo(180);
43+
const [x, y] = graph.getPosition();
44+
45+
dispatchCanvasEvent(graph, CommonEvent.DRAG_START, { targetType: 'canvas' });
46+
dispatchCanvasEvent(graph, CommonEvent.DRAG, { movement: { x: 10, y: 20 }, targetType: 'canvas' });
47+
dispatchCanvasEvent(graph, CommonEvent.DRAG_END);
48+
49+
expect(graph.getRotation()).toBe(180);
50+
expect(graph.getPosition()).toBeCloseTo([x - 10, y - 20]);
51+
});
52+
53+
it('drag 270 rotated canvas', async () => {
54+
await graph.rotateTo(270);
55+
const [x, y] = graph.getPosition();
56+
57+
dispatchCanvasEvent(graph, CommonEvent.DRAG_START, { targetType: 'canvas' });
58+
dispatchCanvasEvent(graph, CommonEvent.DRAG, { movement: { x: 10, y: 20 }, targetType: 'canvas' });
59+
dispatchCanvasEvent(graph, CommonEvent.DRAG_END);
60+
61+
expect(graph.getRotation()).toBe(270);
62+
expect(graph.getPosition()).toBeCloseTo([x + 20, y - 10]);
63+
});
64+
});
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Graph } from '@antv/g6';
2+
3+
export const bugDragRotatedCanvas: TestCase = async (context) => {
4+
const graph = new Graph({
5+
...context,
6+
data: {
7+
nodes: [{ id: 'node1' }, { id: 'node2' }, { id: 'node3' }, { id: 'node4' }, { id: 'node5' }],
8+
edges: [
9+
{ source: 'node1', target: 'node2' },
10+
{ source: 'node1', target: 'node3' },
11+
{ source: 'node1', target: 'node4' },
12+
{ source: 'node2', target: 'node3' },
13+
{ source: 'node3', target: 'node4' },
14+
{ source: 'node4', target: 'node5' },
15+
],
16+
},
17+
layout: {
18+
type: 'grid',
19+
},
20+
behaviors: ['drag-canvas'],
21+
});
22+
23+
await graph.render();
24+
25+
graph.rotateTo(2160 + 60);
26+
27+
return graph;
28+
};

packages/g6/__tests__/demos/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export { behaviorLassoSelect } from './behavior-lasso-select';
2020
export { behaviorOptimizeViewportTransform } from './behavior-optimize-viewport-transform';
2121
export { behaviorScrollCanvas } from './behavior-scroll-canvas';
2222
export { behaviorZoomCanvas } from './behavior-zoom-canvas';
23+
export { bugDragRotatedCanvas } from './bug-drag-rotated-canvas';
2324
export { bugTooltipResize } from './bug-tooltip-resize';
2425
export { canvasCursor } from './canvas-cursor';
2526
export { caseFishbone } from './case-fishbone';

packages/g6/src/behaviors/drag-canvas.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,20 @@ export class DragCanvas extends BaseBehavior<DragCanvasOptions> {
183183
protected async translate(offset: Vector2, animation?: ViewportAnimationEffectTiming) {
184184
offset = this.clampByDirection(offset);
185185
offset = this.clampByRange(offset);
186+
offset = this.clampByRotation(offset);
186187

187188
await this.context.graph.translateBy(offset, animation);
188189
}
189190

191+
private clampByRotation([dx, dy]: Vector2): Vector2 {
192+
const rotation = this.context.graph.getRotation();
193+
if (rotation % 360 === 0) return [dx, dy];
194+
const rad = (rotation * Math.PI) / 180;
195+
const cos = Math.cos(rad);
196+
const sin = Math.sin(rad);
197+
return [dx * cos - dy * sin, dx * sin + dy * cos];
198+
}
199+
190200
private clampByDirection([dx, dy]: Vector2): Vector2 {
191201
const { direction } = this.options;
192202
if (direction === 'x') {

0 commit comments

Comments
 (0)