|
@@ -1,7 +1,7 @@
|
|
|
import type { Canvas, FabricObjectProps, TBrushEventData, XY } from 'fabric';
|
|
import type { Canvas, FabricObjectProps, TBrushEventData, XY } from 'fabric';
|
|
|
import type { PolygonShape } from '../types';
|
|
import type { PolygonShape } from '../types';
|
|
|
|
|
|
|
|
-import { Point, Polygon, Shadow } from 'fabric';
|
|
|
|
|
|
|
+import { Rect, Point, Polygon, Shadow } from 'fabric';
|
|
|
import { ShapeBrush } from './ShapeBrush';
|
|
import { ShapeBrush } from './ShapeBrush';
|
|
|
import { mergeObjectOptions } from '@/lib/fabric';
|
|
import { mergeObjectOptions } from '@/lib/fabric';
|
|
|
|
|
|
|
@@ -114,6 +114,7 @@ type BrushInvalidReason = 'outOfRegion' | 'selfIntersection' | 'degenerateTriang
|
|
|
export class PolygonBrush extends ShapeBrush<PolygonShape> {
|
|
export class PolygonBrush extends ShapeBrush<PolygonShape> {
|
|
|
/** 有效顶点数达到该值即自动闭合落成;默认 100;三角形工具用 3。 */
|
|
/** 有效顶点数达到该值即自动闭合落成;默认 100;三角形工具用 3。 */
|
|
|
vertexTargetCount = 100;
|
|
vertexTargetCount = 100;
|
|
|
|
|
+ private readonly rect: Rect;
|
|
|
|
|
|
|
|
private get vc() {
|
|
private get vc() {
|
|
|
return this.shape === 'triangle' ? 3 : this.vertexTargetCount;
|
|
return this.shape === 'triangle' ? 3 : this.vertexTargetCount;
|
|
@@ -133,15 +134,17 @@ export class PolygonBrush extends ShapeBrush<PolygonShape> {
|
|
|
areaEps = 13;
|
|
areaEps = 13;
|
|
|
|
|
|
|
|
private vertices: XY[] = [];
|
|
private vertices: XY[] = [];
|
|
|
- private moveHint: XY | null = null;
|
|
|
|
|
|
|
+ private moveHint: Point | null = null;
|
|
|
|
|
|
|
|
constructor(canvas: Canvas) {
|
|
constructor(canvas: Canvas) {
|
|
|
super(canvas);
|
|
super(canvas);
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- onMouseDoubleClick(pointer: Point, { e }: TBrushEventData): void {
|
|
|
|
|
- if (!this.canvas._isMainEvent(e)) return;
|
|
|
|
|
- this.tryCloseFromKeyboardOrDblClick({ x: pointer.x, y: pointer.y });
|
|
|
|
|
|
|
+ this.rect = new Rect({
|
|
|
|
|
+ width: this.decimate / 2,
|
|
|
|
|
+ height: this.decimate / 2,
|
|
|
|
|
+ fill: this.color,
|
|
|
|
|
+ selectable: false,
|
|
|
|
|
+ evented: false,
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private closeSnapSq(): number {
|
|
private closeSnapSq(): number {
|
|
@@ -200,6 +203,7 @@ export class PolygonBrush extends ShapeBrush<PolygonShape> {
|
|
|
poly.setCoords();
|
|
poly.setCoords();
|
|
|
this._resetShadow();
|
|
this._resetShadow();
|
|
|
this.canvas.fire('object:created', { object: poly });
|
|
this.canvas.fire('object:created', { object: poly });
|
|
|
|
|
+ this.canvas.remove(this.rect);
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -220,6 +224,11 @@ export class PolygonBrush extends ShapeBrush<PolygonShape> {
|
|
|
return ok;
|
|
return ok;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ onMouseDoubleClick(pointer: Point, { e }: TBrushEventData): void {
|
|
|
|
|
+ if (!this.canvas._isMainEvent(e)) return;
|
|
|
|
|
+ this.tryCloseFromKeyboardOrDblClick({ x: pointer.x, y: pointer.y });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
onMouseDown(pointer: Point, { e }: TBrushEventData): void {
|
|
onMouseDown(pointer: Point, { e }: TBrushEventData): void {
|
|
|
if (!this.canvas._isMainEvent(e)) return;
|
|
if (!this.canvas._isMainEvent(e)) return;
|
|
|
if (this._isOutSideContainer(pointer)) return;
|
|
if (this._isOutSideContainer(pointer)) return;
|
|
@@ -254,6 +263,7 @@ export class PolygonBrush extends ShapeBrush<PolygonShape> {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
this.vertices.push(r);
|
|
this.vertices.push(r);
|
|
|
|
|
+ if (this.vertices.length === 1) this._renderVertex(r);
|
|
|
|
|
|
|
|
if (this.vertices.length === this.vertexTargetCount) {
|
|
if (this.vertices.length === this.vertexTargetCount) {
|
|
|
if (this.isTriangleTool()) {
|
|
if (this.isTriangleTool()) {
|
|
@@ -279,8 +289,12 @@ export class PolygonBrush extends ShapeBrush<PolygonShape> {
|
|
|
this.refreshPreview();
|
|
this.refreshPreview();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- onMouseUp({ e }: TBrushEventData): boolean {
|
|
|
|
|
- if (!this.canvas._isMainEvent(e)) return false;
|
|
|
|
|
|
|
+ onMouseUp(event: TBrushEventData): boolean {
|
|
|
|
|
+ if (this.moveHint) {
|
|
|
|
|
+ this.onMouseDown(this.moveHint, event)
|
|
|
|
|
+ this.moveHint = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!this.canvas._isMainEvent(event.e)) return false;
|
|
|
if (this.isTriangleTool() && this.vertices.length >= 3) return false;
|
|
if (this.isTriangleTool() && this.vertices.length >= 3) return false;
|
|
|
if (this.isPolygonTool()) return this.vertices.length > 0;
|
|
if (this.isPolygonTool()) return this.vertices.length > 0;
|
|
|
return this.vertices.length > 0 && this.vertices.length < 3;
|
|
return this.vertices.length > 0 && this.vertices.length < 3;
|
|
@@ -309,10 +323,17 @@ export class PolygonBrush extends ShapeBrush<PolygonShape> {
|
|
|
reset(): void {
|
|
reset(): void {
|
|
|
this.vertices = [];
|
|
this.vertices = [];
|
|
|
this.moveHint = null;
|
|
this.moveHint = null;
|
|
|
|
|
+ this.canvas.remove(this.rect);
|
|
|
this.canvas.clearContext(this.canvas.contextTop);
|
|
this.canvas.clearContext(this.canvas.contextTop);
|
|
|
this.canvas.requestRenderAll();
|
|
this.canvas.requestRenderAll();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ private _renderVertex(point: Point) {
|
|
|
|
|
+ this.rect.setXY(point);
|
|
|
|
|
+ this.rect.fill = this.color;
|
|
|
|
|
+ this.canvas.add(this.rect);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
protected override cleanupBrushState(): void {
|
|
protected override cleanupBrushState(): void {
|
|
|
this.vertices = [];
|
|
this.vertices = [];
|
|
|
this.moveHint = null;
|
|
this.moveHint = null;
|