Skip to content

Commit d88aef1

Browse files
author
Yan Heng
committed
feat: 增加矩形绘制工具
1 parent c9d37d5 commit d88aef1

File tree

6 files changed

+69
-53
lines changed

6 files changed

+69
-53
lines changed

main/src/view/canvas/index.vue

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<script setup lang="ts">
22
import { onMounted, ref } from 'vue';
3-
import { App } from '@pictode/core';
3+
import { App, RectTool, SelectTool } from '@pictode/core';
44
55
const containerRef = ref<HTMLDivElement>();
66
77
const app = new App();
8+
const selectTool = new SelectTool(app);
9+
const rectTool = new RectTool(app);
810
onMounted(() => {
911
if (containerRef.value) {
1012
app.mount(containerRef.value);
@@ -15,9 +17,9 @@ onMounted(() => {
1517
<template>
1618
<div class="wrapper">
1719
<div class="tools">
18-
<button @click="app.setModel('select')">选择🖱️</button>
19-
<button @click="app.setModel('drawing')">铅笔✏️</button>
20-
<button @click="app.setModel('rect')">矩形⬜️</button>
20+
<button @click="app.setTool(selectTool)">选择🖱️</button>
21+
<!-- <button @click="app.setModel('drawing')">铅笔✏️</button> -->
22+
<button @click="app.setTool(rectTool)">矩形⬜️</button>
2123
</div>
2224
<div ref="containerRef" class="container"></div>
2325
</div>

packages/core/src/app.ts

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import { BaseService } from '@pictode/utils';
22
import { fabric } from 'fabric';
33

4-
import { Rect } from './customs/rect';
5-
import { AppOption, ControlsOption, EventArgs, Model, Plugin, ToolStrategy } from './types';
4+
import { MouseService } from './services/mouse';
5+
import { AppOption, ControlsOption, EventArgs, Plugin, ToolStrategy } from './types';
66
import { DEFAULT_APP_OPTION } from './utils';
77

88
export class App extends BaseService<EventArgs> {
99
public canvas: fabric.Canvas;
10+
public mouseService: MouseService;
11+
public currentTool: ToolStrategy | null = null;
1012

11-
private currentTool: ToolStrategy | null = null;
1213
private option: AppOption & { controls: ControlsOption };
1314
private installedPlugins: Map<string, Plugin> = new Map();
1415
private canvasEl: HTMLCanvasElement;
15-
private curPointer: fabric.Point = new fabric.Point(0, 0);
1616

1717
constructor(option?: AppOption) {
1818
super();
@@ -22,11 +22,11 @@ export class App extends BaseService<EventArgs> {
2222
backgroundColor: option?.backgroundColor,
2323
});
2424
this.setControls(this.option.controls);
25-
this.canvas.on('mouse:move', ({ e }: fabric.IEvent<MouseEvent>) => {
26-
const { x, y } = this.canvas.getPointer(e);
27-
this.curPointer.setXY(x, y);
28-
console.log('===>', x, y);
29-
});
25+
this.mouseService = new MouseService(this);
26+
}
27+
28+
public get pointer(): fabric.Point {
29+
return this.mouseService.pointer;
3030
}
3131

3232
public mount(element: HTMLElement) {
@@ -35,10 +35,9 @@ export class App extends BaseService<EventArgs> {
3535
width: element.clientWidth,
3636
height: element.clientHeight,
3737
});
38-
this.setModel('select');
3938
}
4039

41-
public setControls(controls: ControlsOption | boolean): App {
40+
public setControls(controls: ControlsOption | boolean): void {
4241
this.option.controls = controls;
4342
if (typeof controls === 'boolean') {
4443
this.option.controls.hasControls = controls;
@@ -52,45 +51,10 @@ export class App extends BaseService<EventArgs> {
5251
}
5352
});
5453
this.render(true);
55-
return this;
5654
}
5755

58-
public setTool(tool: ToolStrategy): App {
56+
public setTool(tool: ToolStrategy): void {
5957
this.currentTool = tool;
60-
return this;
61-
}
62-
63-
public setModel(model: Model): App {
64-
const rect = new Rect({
65-
width: 200,
66-
height: 100,
67-
top: 20,
68-
left: 20,
69-
fill: 'transparent',
70-
stroke: 'blue',
71-
strokeWidth: 5,
72-
rx: 5,
73-
ry: 5,
74-
});
75-
switch (model) {
76-
case 'select':
77-
this.canvas.isDrawingMode = false;
78-
this.canvas.selection = true;
79-
this.canvas.selectionColor = 'rgba(157, 157, 231, 0.5)';
80-
this.canvas.selectionBorderColor = 'rgb(157, 157, 231)';
81-
this.canvas.selectionLineWidth = 2;
82-
break;
83-
case 'drawing':
84-
this.canvas.isDrawingMode = true;
85-
this.canvas.selection = false;
86-
this.canvas.freeDrawingBrush.color = 'red';
87-
this.canvas.freeDrawingBrush.width = 20;
88-
break;
89-
case 'rect':
90-
this.canvas.add(rect);
91-
break;
92-
}
93-
return this;
9458
}
9559

9660
public render(asyncRedraw?: boolean): void {

packages/core/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
export * from './app';
22
export * from './types';
33
export * from './decorators/expand-app';
4+
export * from './tools/rect-tool';
5+
export * from './tools/select-tool';

packages/core/src/services/mouse.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,23 @@ export class MouseService extends Service {
5454

5555
private onMouseDown(event: IMouseEvent): void {
5656
this.event = event.e;
57+
if (this.app.currentTool) {
58+
this.app.currentTool.onMouseDown(this.event);
59+
}
5760
}
5861

5962
private onMouseUp(event: IMouseEvent): void {
6063
this.event = event.e;
64+
if (this.app.currentTool) {
65+
this.app.currentTool.onMouseUp(this.event);
66+
}
6167
}
6268

6369
private onMouseMove(event: IMouseEvent): void {
6470
this.event = event.e;
71+
if (this.app.currentTool) {
72+
this.app.currentTool.onMouseMove(this.event);
73+
}
6574
}
6675

6776
private onMouseDoubleClick(event: IMouseEvent): void {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Rect } from '../customs/rect';
2+
import { ToolStrategy } from '../types';
3+
4+
export class RectTool extends ToolStrategy {
5+
private isDrawing: boolean = false;
6+
private rect: Rect | null = null;
7+
8+
public onMouseDown(): void {
9+
this.isDrawing = true;
10+
const pointer = this.app.pointer;
11+
this.rect = new Rect({
12+
left: pointer.x,
13+
top: pointer.y,
14+
width: 0,
15+
height: 0,
16+
fill: 'transparent',
17+
stroke: 'black',
18+
strokeWidth: 2,
19+
});
20+
this.app.canvas.add(this.rect);
21+
}
22+
23+
public onMouseMove(): void {
24+
if (!this.isDrawing || !this.rect) {
25+
return;
26+
}
27+
const pointer = this.app.pointer;
28+
this.rect.set({
29+
width: pointer.x - (this.rect.left ?? 0),
30+
height: pointer.y - (this.rect.top ?? 0),
31+
});
32+
this.app.render();
33+
}
34+
35+
public onMouseUp(): void {
36+
this.isDrawing = false;
37+
this.rect = null;
38+
}
39+
}
40+
41+
export default RectTool;

packages/core/src/types.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ export abstract class Service {
3535

3636
export interface EventArgs {}
3737

38-
export type Model = 'select' | 'drawing' | 'rect' | 'circle';
39-
4038
export interface ControlVisible {
4139
bl?: boolean;
4240
br?: boolean;

0 commit comments

Comments
 (0)