Skip to content

Commit 6c4daa1

Browse files
author
Yan Heng
committed
feat: 抽取selector服务,实现系统选择功能
1 parent a92e36e commit 6c4daa1

File tree

2 files changed

+84
-41
lines changed

2 files changed

+84
-41
lines changed

packages/core/src/app.ts

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ import { BaseService } from '@pictode/utils';
22
import Konva from 'konva';
33

44
import { MouseService } from './services/mouse';
5+
import { Selector } from './services/selector';
56
import { ChildType, EventArgs, KonvaMouseEvent, Plugin, Tool } from './types';
67
import { Point } from './utils';
78

89
export class App extends BaseService<EventArgs> {
910
public stage: Konva.Stage;
1011
public currentTool: Tool | null = null;
1112
public mainLayer: Konva.Layer;
12-
public selected: ChildType[] = [];
1313

14-
private selector: Konva.Transformer;
1514
private mouse: MouseService;
15+
private selector: Selector;
1616
private containerElement: HTMLDivElement;
1717
private installedPlugins: Map<string, Plugin> = new Map();
1818

@@ -36,36 +36,7 @@ export class App extends BaseService<EventArgs> {
3636
this.mainLayer.name('pictode:main:layer');
3737
this.stage.add(this.mainLayer);
3838

39-
this.selector = new Konva.Transformer({
40-
padding: 3,
41-
borderStroke: 'rgb(157, 157, 231)',
42-
borderStrokeWidth: 1,
43-
anchorSize: 8,
44-
anchorStroke: 'rgb(157, 157, 231)',
45-
anchorCornerRadius: 3,
46-
anchorStrokeWidth: 1,
47-
rotateAnchorOffset: 20,
48-
});
49-
this.selector.anchorStyleFunc((anchor) => {
50-
if (!anchor.hasName('rotater')) {
51-
return;
52-
}
53-
const setAnchorCursor = (cursor: string = '') => {
54-
const anchorStage = anchor.getStage();
55-
if (!anchorStage || !anchorStage.content) {
56-
return;
57-
}
58-
anchorStage.content.style.cursor = cursor;
59-
};
60-
anchor.on('mouseenter', () => {
61-
setAnchorCursor('grab');
62-
});
63-
anchor.on('mouseout', () => {
64-
setAnchorCursor();
65-
});
66-
});
67-
this.mainLayer.add(this.selector);
68-
39+
this.selector = new Selector(this);
6940
this.mouse = new MouseService(this);
7041
}
7142

@@ -101,15 +72,7 @@ export class App extends BaseService<EventArgs> {
10172
}
10273

10374
public select(...children: ChildType[]): void {
104-
this.selected.forEach((child) => child.draggable(false));
105-
this.selected = [];
106-
this.selector.nodes([]);
107-
children.forEach((child) => {
108-
child.draggable(true);
109-
this.selected.push(child);
110-
});
111-
this.selector.nodes(children);
112-
this.selector.moveToTop();
75+
this.selector.select(...children);
11376
}
11477

11578
public selectByEvent(event: KonvaMouseEvent): void {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import Konva from 'konva';
2+
3+
import { App } from '../app';
4+
import { Rect } from '../customs/rect';
5+
import { ChildType, Service } from '../types';
6+
7+
export class Selector extends Service {
8+
public selected: ChildType[];
9+
public optionLayer: Konva.Layer;
10+
11+
private selector: Konva.Transformer;
12+
private rubberRect: Rect;
13+
14+
constructor(app: App) {
15+
super(app);
16+
this.selected = [];
17+
this.optionLayer = new Konva.Layer();
18+
this.optionLayer.name('pictode:option:layer');
19+
this.app.stage.add(this.optionLayer);
20+
21+
this.selector = new Konva.Transformer({
22+
padding: 3,
23+
borderStroke: 'rgb(157, 157, 231)',
24+
borderStrokeWidth: 1,
25+
anchorSize: 8,
26+
anchorStroke: 'rgb(157, 157, 231)',
27+
anchorCornerRadius: 3,
28+
anchorStrokeWidth: 1,
29+
rotateAnchorOffset: 20,
30+
});
31+
this.selector.anchorStyleFunc((anchor) => {
32+
if (!anchor.hasName('rotater')) {
33+
return;
34+
}
35+
const setAnchorCursor = (cursor: string = '') => {
36+
const anchorStage = anchor.getStage();
37+
if (!anchorStage || !anchorStage.content) {
38+
return;
39+
}
40+
anchorStage.content.style.cursor = cursor;
41+
};
42+
anchor.on('mouseenter', () => {
43+
setAnchorCursor('grab');
44+
});
45+
anchor.on('mouseout', () => {
46+
setAnchorCursor();
47+
});
48+
});
49+
50+
this.optionLayer.add(this.selector);
51+
52+
this.rubberRect = new Rect({
53+
stroke: 'red',
54+
dash: [2, 2],
55+
listening: false,
56+
});
57+
this.optionLayer.add(this.rubberRect);
58+
}
59+
60+
public select(...children: ChildType[]): void {
61+
this.selected.forEach((child) => child.draggable(false));
62+
this.selected = [];
63+
this.selector.nodes([]);
64+
children.forEach((child) => {
65+
child.draggable(true);
66+
this.selected.push(child);
67+
});
68+
this.selector.nodes(children);
69+
this.selector.moveToTop();
70+
this.app.render();
71+
}
72+
73+
public dispose(): void {
74+
this.selected = [];
75+
this.selector.destroy();
76+
this.optionLayer.destroy();
77+
}
78+
}
79+
80+
export default Selector;

0 commit comments

Comments
 (0)