فهرست منبع

Merge branch 'master' of http://39.106.8.246:3003/web/sagacloud-web

haojianlong 5 سال پیش
والد
کامیت
036305d9e6

+ 1 - 1
saga-web-base/package.json

@@ -1,6 +1,6 @@
 {
     "name": "@saga-web/base",
-    "version": "2.1.14",
+    "version": "2.1.15",
     "description": "上格云Web基础库。",
     "main": "lib/index.js",
     "types": "lib/index.d.js",

+ 23 - 0
saga-web-base/src/extensions/SObjectExtension.ts

@@ -0,0 +1,23 @@
+/**
+ * 定义与实现 Object 扩展方法
+ *
+ * @author  庞利祥
+ */
+declare global {
+    /**
+     * 定义 Object 对象扩展方法
+     */
+    interface Object {
+        /** 定义 Object 对象 toJson() 扩展方法 */
+        toJson(): string;
+    }
+}
+
+/**
+ * 实现 Object 对象 toJson() 扩展方法
+ */
+Object.prototype.toJson = function (): string {
+    return JSON.stringify(this);
+};
+
+export {};

+ 2 - 0
saga-web-base/src/index.ts

@@ -1,3 +1,5 @@
+import "./extensions/SObjectExtension";
+
 import { SMouseButton } from "./enums/SMouseButton";
 import { STouchState } from "./enums/STouchState";
 export { SMouseButton, STouchState };

+ 213 - 42
saga-web-big/src/items/SLineItem.ts

@@ -1,4 +1,4 @@
-import { SColor, SLine, SPainter, SPoint } from "@saga-web/draw/lib";
+import { SColor, SLine, SPainter, SPoint, SRect } from "@saga-web/draw/lib";
 import { SMouseEvent } from "@saga-web/base";
 import { SMathUtil } from "../utils/SMathUtil";
 import { SRelationState } from "..";
@@ -7,13 +7,30 @@ import { SGraphItem } from "@saga-web/graph/lib";
 /**
  * 直线item
  *
+ * @author  张宇(taohuzy@163.com)
  * */
 
 export class SLineItem extends SGraphItem {
-    /** 线段起始点   */
-    p1: SPoint | undefined;
-    /** 线段终止点   */
-    p2: SPoint | undefined;
+    /** X坐标最小值  */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X坐标最大值  */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y坐标最小值  */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y坐标最大值  */
+    private maxY = Number.MIN_SAFE_INTEGER;
+
+    /** 线段   */
+    _line: SPoint[] = [];
+    get line(): SPoint[] {
+        return this._line;
+    }
+    set line(arr: SPoint[]) {
+        this._line = arr;
+        this._xyzListToSPointList(arr);
+        this.update();
+    }
+
     /** 是否完成绘制  */
     _status: SRelationState = SRelationState.Create;
     get status(): SRelationState {
@@ -23,6 +40,7 @@ export class SLineItem extends SGraphItem {
         this._status = v;
         this.update();
     }
+
     /** 线条颜色    */
     _strokeColor: string = "#000000";
     get strokeColor(): string {
@@ -32,6 +50,7 @@ export class SLineItem extends SGraphItem {
         this._strokeColor = v;
         this.update();
     }
+
     /** 填充色 */
     _fillColor: string = "#2196f3";
     get fillColor(): string {
@@ -41,6 +60,7 @@ export class SLineItem extends SGraphItem {
         this._fillColor = v;
         this.update();
     }
+
     /** 线条宽度    */
     _lineWidth: number = 1;
     get lineWidth(): number {
@@ -50,24 +70,29 @@ export class SLineItem extends SGraphItem {
         this._lineWidth = v;
         this.update();
     }
+
     /** 拖动灵敏度   */
     dis: number = 10;
+
     /** 拖动灵敏度   */
     sceneDis: number = 10;
 
+    /** 当前点索引   */
+    curIndex: number = -1;
+
     /**
      * 构造函数
      *
      * @param   parent  父级
-     * @param   line    线段
+     * @param   line    坐标集合
      * */
-    constructor(parent: SGraphItem | null, line: SLine);
+    constructor(parent: SGraphItem | null, line: SPoint[]);
 
     /**
      * 构造函数
      *
      * @param   parent  父级
-     * @param   point   线段起点
+     * @param   point   第一个点坐标
      * */
     constructor(parent: SGraphItem | null, point: SPoint);
 
@@ -75,19 +100,54 @@ export class SLineItem extends SGraphItem {
      * 构造函数
      *
      * @param   parent  父级
-     * @param   l       线段or线段起点
+     * @param   l       坐标集合|第一个点坐标
      * */
-    constructor(parent: SGraphItem | null, l: SPoint | SLine) {
+    constructor(parent: SGraphItem | null, l: SPoint | SPoint[]) {
         super(parent);
         if (l instanceof SPoint) {
-            this.p1 = l;
+            this.line.push(l);
         } else {
-            this.p1 = l.p1;
-            this.p2 = l.p2;
+            this.line = l;
         }
     }
 
     /**
+     * 添加点至数组中
+     *
+     * @param   p       添加的点
+     * @param   index   添加到的索引
+     * */
+    private addPoint(p: SPoint): void {
+        if (this.line.length < 2) {
+            this.line.push(p);
+        } else {
+            this.line[1] = p;
+            this.status = SRelationState.Normal;
+        }
+        this._xyzListToSPointList(this.line);
+        this.update();
+    } // Function addPoint()
+
+    /**
+     * 鼠标双击事件
+     *
+     * @param	event         事件参数
+     * @return	boolean
+     */
+    onDoubleClick(event: SMouseEvent): boolean {
+        if (this.contains(event.x, event.y)) {
+            // 判断是否点击到线上
+            if (this.status == SRelationState.Normal) {
+                this.status = SRelationState.Edit;
+            } else if ((this.status = SRelationState.Edit)) {
+                this.status = SRelationState.Normal;
+            }
+            this.update();
+        }
+        return true;
+    } // Function onDoubleClick()
+
+    /**
      * 鼠标按下事件
      *
      * @param   event   鼠标事件
@@ -97,7 +157,10 @@ export class SLineItem extends SGraphItem {
         if (this.status == SRelationState.Normal) {
             return super.onMouseDown(event);
         } else if (this.status == SRelationState.Edit) {
+            // 判断是否点击到端点上(获取端点索引值)
+            this.findNearestPoint(new SPoint(event.x, event.y));
         } else if (this.status == SRelationState.Create) {
+            this.addPoint(new SPoint(event.x, event.y));
             return true;
         }
         this.$emit("mousedown");
@@ -105,6 +168,19 @@ export class SLineItem extends SGraphItem {
     } // Function onMouseDown()
 
     /**
+     * 鼠标抬起事件
+     *
+     * @param	event         事件参数
+     * @return	boolean
+     */
+    onMouseUp(event: SMouseEvent): boolean {
+        if (this._status == SRelationState.Edit) {
+            this.curIndex = -1;
+        }
+        return true;
+    } // Function onMouseUp()
+
+    /**
      * 鼠标移动事件
      *
      * @param   event   鼠标事件
@@ -112,32 +188,72 @@ export class SLineItem extends SGraphItem {
      * */
     onMouseMove(event: SMouseEvent): boolean {
         if (this.status == SRelationState.Create) {
-            if (!this.p2) {
-                this.p2 = new SPoint(event.x, event.y);
-            } else {
-                this.p2.x = event.x;
-                this.p2.y = event.y;
+            if (this.line[0] instanceof SPoint) {
+                this.line[1] = new SPoint(event.x, event.y);
+            }
+        } else if (this.status == SRelationState.Edit) {
+            if (-1 != this.curIndex) {
+                this.line[this.curIndex].x = event.x;
+                this.line[this.curIndex].y = event.y;
             }
-            return true;
         } else {
             return super.onMouseMove(event);
         }
+        this._xyzListToSPointList(this.line);
+        this.update();
+        return true;
     } // Function onMouseMove()
 
     /**
-     * 鼠标移动事件
+     * 获取点击点与Point[]中的点距离最近点
      *
-     * @param   event   鼠标事件
-     * @return  是否处理事件
+     * @param   p   鼠标点击点
      * */
-    onMouseUp(event: SMouseEvent): boolean {
-        if (this.status == SRelationState.Create) {
-            this.status = SRelationState.Edit;
-            return true;
-        } else {
-            return super.onMouseUp(event);
+    findNearestPoint(p: SPoint): void {
+        let len = this.sceneDis;
+        for (let i = 0; i < 2; i++) {
+            let dis = SMathUtil.pointDistance(
+                p.x,
+                p.y,
+                this.line[i].x,
+                this.line[i].y
+            );
+            if (dis < len) {
+                len = dis;
+                this.curIndex = i;
+            }
         }
-    } // Function onMouseUp()
+    } // Function findNearestPoint()
+
+    /**
+     * xyz数据转换为SPoint格式函数;获取外接矩阵参数
+     *
+     * @param arr    外层传入的数据PointList
+     */
+    protected _xyzListToSPointList(arr: SPoint[]): void {
+        if (arr.length) {
+            this.minX = Number.MAX_SAFE_INTEGER;
+            this.maxX = Number.MIN_SAFE_INTEGER;
+            this.minY = Number.MAX_SAFE_INTEGER;
+            this.maxY = Number.MIN_SAFE_INTEGER;
+            arr.forEach(it => {
+                let x = it.x,
+                    y = it.y;
+                if (x < this.minX) {
+                    this.minX = x;
+                }
+                if (y < this.minY) {
+                    this.minY = y;
+                }
+                if (x > this.maxX) {
+                    this.maxX = x;
+                }
+                if (y > this.maxY) {
+                    this.maxY = y;
+                }
+            });
+        }
+    }
 
     /**
      * 判断点是否在区域内
@@ -147,11 +263,11 @@ export class SLineItem extends SGraphItem {
      * @return  true-是
      */
     contains(x: number, y: number): boolean {
-        if (this.p1 instanceof SPoint && this.p2 instanceof SPoint) {
+        if (this.line.length == 2) {
             let p = new SPoint(x, y);
             if (
-                SMathUtil.pointToLine(p, new SLine(this.p1, this.p2)).MinDis <
-                this.dis
+                SMathUtil.pointToLine(p, new SLine(this.line[0], this.line[1]))
+                    .MinDis < this.dis
             ) {
                 return true;
             }
@@ -160,6 +276,34 @@ export class SLineItem extends SGraphItem {
     } // Function contains()
 
     /**
+     * 取消操作item事件
+     *
+     * */
+    cancelOperate(): void {
+        if (this.status == SRelationState.Create) {
+            this.parent = null;
+            this.releaseItem();
+        } else if (this.status == SRelationState.Edit) {
+            this.status = SRelationState.Normal;
+            this.releaseItem();
+        }
+    } // Function cancelOperate()
+
+    /**
+     * Item对象边界区域
+     *
+     * @return	SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
      * Item绘制操作
      *
      * @param   painter painter对象
@@ -168,18 +312,45 @@ export class SLineItem extends SGraphItem {
         this.sceneDis = painter.toPx(this.dis);
         painter.pen.lineWidth = painter.toPx(this.lineWidth);
         painter.pen.color = new SColor(this.strokeColor);
-        if (this.p1 instanceof SPoint && this.p2 instanceof SPoint) {
-            // 绘制基本图形
-            painter.drawLine(this.p1, this.p2);
-            // 编辑态
-            if (this.status == SRelationState.Edit) {
-                painter.brush.color = SColor.White;
+        if (this.line.length == 2) {
+            // 绘制外轮廓
+            // painter.brush.color = SColor.Transparent;
+            // painter.pen.color = new SColor("#128eee");
+            // painter.drawRect(this.boundingRect());
 
-                // painter.brush.color = new SColor(this.fillColor);
+            // 绘制直线
+            painter.pen.color = new SColor(this.strokeColor);
+            painter.drawLine(this.line[0], this.line[1]);
 
-                painter.drawCircle(this.p1.x, this.p1.y, painter.toPx(5));
-
-                painter.drawCircle(this.p2.x, this.p2.y, painter.toPx(5));
+            if (
+                this.status == SRelationState.Edit ||
+                this.status == SRelationState.Create
+            ) {
+                // 绘制端点
+                painter.brush.color = new SColor(this.fillColor);
+                painter.drawCircle(
+                    this.line[0].x,
+                    this.line[0].y,
+                    painter.toPx(5)
+                );
+                painter.drawCircle(
+                    this.line[1].x,
+                    this.line[1].y,
+                    painter.toPx(5)
+                );
+            }
+        } else if (this.line.length == 1) {
+            if (
+                this.status == SRelationState.Edit ||
+                this.status == SRelationState.Create
+            ) {
+                // 绘制端点
+                painter.brush.color = new SColor(this.fillColor);
+                painter.drawCircle(
+                    this.line[0].x,
+                    this.line[0].y,
+                    painter.toPx(5)
+                );
             }
         }
     } // Function onDraw()

+ 45 - 0
saga-web-draw/__tests__/types/SPoint.test.ts

@@ -0,0 +1,45 @@
+import { SPoint } from "../../src";
+
+test("构造函数", () => {
+    expect(new SPoint().toJson()).toBe("{\"x\":0,\"y\":0}");
+    expect(new SPoint(10, 10).toJson()).toBe("{\"x\":10,\"y\":10}");
+});
+
+test("属性修改", () => {
+    const p = new SPoint();
+    expect(p.toJson()).toBe("{\"x\":0,\"y\":0}");
+
+    p.y = 10;
+    expect(p.toJson()).toBe("{\"x\":0,\"y\":10}");
+    p.x = -10;
+    expect(p.toJson()).toBe("{\"x\":-10,\"y\":10}");
+
+    p.setPoint(-100, -30);
+    expect(p.toJson()).toBe("{\"x\":-100,\"y\":-30}");
+
+    p.setPoint(new SPoint(-5, -12));
+    expect(p.toJson()).toBe("{\"x\":-5,\"y\":-12}");
+});
+
+test("setPoint()", () => {
+    const p = new SPoint();
+    p.setPoint(-100, -30);
+    expect(p.toJson()).toBe("{\"x\":-100,\"y\":-30}");
+
+    p.setPoint(new SPoint(-5, -12));
+    expect(p.toJson()).toBe("{\"x\":-5,\"y\":-12}");
+});
+
+test("manhattanLength()", () => {
+    const p = new SPoint(10, 20);
+    expect(p.manhattanLength()).toBe(30);
+
+    p.setPoint(-10, 20);
+    expect(p.manhattanLength()).toBe(30);
+
+    p.setPoint(10, -20);
+    expect(p.manhattanLength()).toBe(30);
+
+    p.setPoint(-10, -20);
+    expect(p.manhattanLength()).toBe(30);
+});

+ 1 - 1
saga-web-draw/package.json

@@ -33,7 +33,7 @@
         "typescript": "^3.5.3"
     },
     "dependencies": {
-        "@saga-web/base": "^2.1.12"
+        "@saga-web/base": "^2.1.15"
     },
     "jest": {
         "setupFiles": [

+ 1 - 1
saga-web-draw/src/engines/SCanvasPaintEngine.ts

@@ -491,7 +491,7 @@ export class SCanvasPaintEngine extends SPaintEngine {
     private setFont(): void {
         this._canvas.font = `${this.state.font.size}px ${this.state.font.name}`;
         this.setTextAlign(this.state.font.textAlign);
-        this.setBaseLine(this.state.font.textBaseLine);
+        // this.setBaseLine(this.state.font.textBaseLine);
         this.setTextDirection(this.state.font.textDirection);
     } // Function setFont()