Explorar o código

与persagy 统一 图片item抛出事件更改该

haojianlong %!s(int64=4) %!d(string=hai) anos
pai
achega
90fb9a8646

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

@@ -1,6 +1,6 @@
 {
     "name": "@saga-web/graph",
-    "version": "2.1.131",
+    "version": "2.1.132",
     "description": "上格云二维图形引擎。",
     "main": "lib/index.js",
     "types": "lib/index.d.js",

+ 11 - 0
saga-web-graph/src/SGraphItem.ts

@@ -159,6 +159,12 @@ export class SGraphItem extends SObject {
         this.update();
     } // Set selected
 
+    /** 是否可修改大小 */
+    _resizeable: boolean = true;
+
+    /** 选中时是否显示选择器 */
+    showSelect: boolean = true;
+
     /** 是否进行变形 */
     isTransform = true;
 
@@ -433,6 +439,7 @@ export class SGraphItem extends SObject {
                 console.log(e);
             }
         }
+        this.$emit("onMouseDown", event);
         // 移动
         if (this.moveable) {
             this._mouseDownPos = new SPoint(event.x, event.y);
@@ -464,6 +471,7 @@ export class SGraphItem extends SObject {
                 return true;
             }
         }
+        this.$emit("onMouseMove", event);
         if (this.scene && this.scene.view) {
             this.scene.view.cursor = this.cursor;
         }
@@ -537,6 +545,7 @@ export class SGraphItem extends SObject {
         if (this.selectable) {
             select = this.clickSelect(event);
         }
+        this.$emit("onMouseUp", event);
         this._isMoving = false;
         this.releaseItem();
         if (this.scene) {
@@ -552,6 +561,7 @@ export class SGraphItem extends SObject {
      * @return  boolean
      */
     onMouseEnter(event: SMouseEvent): boolean {
+        this.$emit("onMouseEnter", event);
         return false;
     } // Function onMouseEnter()
 
@@ -562,6 +572,7 @@ export class SGraphItem extends SObject {
      * @return  boolean
      */
     onMouseLeave(event: SMouseEvent): boolean {
+        this.$emit("onMouseLeave", event);
         return false;
     } // Function onMouseLeave()
 

+ 77 - 92
saga-web-graph/src/SGraphScene.ts

@@ -1,22 +1,22 @@
-import { SMouseEvent, SMatrix } from "@saga-web/base/lib";
-import {SPainter, SPoint, SRect} from "@saga-web/draw/lib";
+import { SMouseEvent, SMatrix } from "@saga-web/base";
+import { SPainter, SPoint, SRect } from "@saga-web/draw";
 import { SGraphItem } from "./SGraphItem";
 import { SGraphView } from "./SGraphView";
 import { SGraphSelectContainer } from "./SGraphSelectContainer";
 
 /**
- * Graphy图形引擎场景类
+ * Graph 图形引擎场景类
  *
- * @author  庞利祥(sybotan@126.com)
+ * @author 庞利祥 <sybotan@126.com>
  */
 export class SGraphScene {
     /** 展示场景的视图 */
     view: SGraphView | null = null;
     /** 根节点 */
     protected root: SGraphItem = new SGraphItem();
-    /** 当前捕获Item */
+    /** 当前捕获 Item */
     grabItem: SGraphItem | null = null;
-    /** 鼠标所在Item */
+    /** 鼠标所在 Item */
     hoverItem: SGraphItem | null = null;
     /** 选择器 */
     selectContainer: SGraphSelectContainer = new SGraphSelectContainer();
@@ -26,85 +26,94 @@ export class SGraphScene {
      */
     constructor() {
         this.root.scene = this;
-    } // Constructor
+        // this.addItem(this.selectContainer);
+    }
 
     /**
-     * 添加item对象到场景。
+     * 添加 item 对象到场景。
      *
-     * @param   item        添加的对象
+     * @param item        添加的对象
      */
     addItem(item: SGraphItem): void {
         item.parent = this.root;
-    } // Functin addItem()
+    }
 
     /**
-     * 从场景中移除Item。
+     * 从场景中移除 Item。
      *
-     * @param   item        被移除的对象
+     * @param item        被移除的对象
      */
     removeItem(item: SGraphItem): void {
         item.parent = null;
-    } // Function removeItem()
+    }
 
     /**
      * 绘制场景
      *
-     * @param   painter     painter对象
-     * @param   rect        更新绘制区域
+     * @param painter     绘制对象
+     * @param rect        更新绘制区域
      */
     drawScene(painter: SPainter, rect: SRect): void {
         this.root.onPaint(painter, rect);
-    } // Function drawScene()
+    }
 
     /**
      * 绘制背景
      *
-     * @param   painter     painter对象
-     * @param   rect        更新绘制区域
+     * @param painter     绘制对象
+     * @param rect        更新绘制区域
      */
-    drawBackground(painter: SPainter, rect: SRect) {
+    drawBackground(painter: SPainter, rect: SRect): void {
         // DO NOTHING
-    } // Function drawBackground()
+    }
 
     /**
      * 绘制前景
      *
-     * @param   painter     painter对象
-     * @param   rect        更新绘制区域
+     * @param painter     绘制对象
+     * @param rect        更新绘制区域
      */
-    drawForeground(painter: SPainter, rect: SRect) {
+    drawForeground(painter: SPainter, rect: SRect): void {
         // DO NOTHING
-    } // Function drawForeground()
+    }
 
     /**
-     * 所有item占用的矩形区域
+     * 所有 item 占用的矩形区域
+     *
+     * @param flag 是否只对可见 item 处理
+     * @return 所有 item 占用的矩形区域
      */
-    allItemRect(): SRect | null {
+    allItemRect(flag: boolean = true): SRect | null {
         let rect: SRect | null = null;
-
-        // 依次取item列中的所有item。将所有item的边界做并焦处理。
+        // 依次取 item 列中的所有 item。将所有 item 的边界做并焦处理。
         for (let item of this.root.children) {
-            if (rect == null) {
-                rect = item.boundingRect().translated(item.pos.x, item.pos.y);
-            } else {
-                rect.union(
-                    item.boundingRect().translated(item.pos.x, item.pos.y)
-                );
+            if ((flag && item.visible) || !flag) {
+                if (rect == null) {
+                    rect = item
+                        .boundingRect()
+                        .translated(item.pos.x, item.pos.y);
+                } else {
+                    rect.union(
+                        item.boundingRect().translated(item.pos.x, item.pos.y)
+                    );
+                }
             }
         }
 
         return rect;
-    } // Function allItemRect()
+    }
 
     /**
-     * 被选中item占用的矩形区域
+     * 被选中 item 占用的矩形区域
+     *
+     * @return 被选中 item 占用的矩形区域
      */
     selectedItemRect(): SRect | null {
         let rect: SRect | null = null;
 
-        // 依次取item列中的所有item。将所有item的边界做并焦处理。
+        // 依次取 item 列中的所有 item。将所有 item 的边界做并焦处理。
         for (let item of this.root.children) {
-            // 如果item未被选中,则去选择下一个item
+            // 如果 item 未被选中,则去选择下一个 item
             if (!item.selected) {
                 continue;
             }
@@ -119,46 +128,32 @@ export class SGraphScene {
         }
 
         return rect;
-    } // Function selectedItemRect()
+    }
 
     /**
      * 获得选中的对象列表
      *
-     * @return  选中对象列表
+     * @return 选中对象列表
      */
     selectedItems(): SGraphItem[] {
         let itemList = Array<SGraphItem>();
         for (let item of this.root.children) {
-            // 如果item未被选中,则去选择下一个item
+            // 如果 item 未被选中,则去选择下一个 item
             if (item.selected) {
                 itemList.push(item);
             }
         }
         return itemList;
-    } // Function selectedItems()
+    }
 
     // =================================================================================================================
     // 事件
-    // /**
-    //  * 鼠标单击事件
-    //  *
-    //  * @param   event   保存事件参数
-    //  * @return  boolean
-    //  */
-    // onClick(event: SMouseEvent): boolean {
-    //     if (this.grabItem != null) {
-    //         return this.grabItem.onClick(
-    //             SGraphScene.toGrabItemMotionEvent(this.grabItem, event)
-    //         );
-    //     }
-    //     return this.root.onClick(event);
-    // } // Function onClick()
 
     /**
      * 鼠标双击事件
      *
-     * @param   event   保存事件参数
-     * @return  boolean
+     * @param event   保存事件参数
+     * @return 是否处理事件
      */
     onDoubleClick(event: SMouseEvent): boolean {
         if (this.grabItem != null) {
@@ -167,13 +162,13 @@ export class SGraphScene {
             );
         }
         return this.root.onDoubleClick(event);
-    } // Function onDoubleClick()
+    }
 
     /**
      * 鼠标按下事件
      *
-     * @param   event   保存事件参数
-     * @return  boolean
+     * @param event   保存事件参数
+     * @return 是否处理事件
      */
     onMouseDown(event: SMouseEvent): boolean {
         if (this.grabItem != null) {
@@ -182,17 +177,17 @@ export class SGraphScene {
             );
         }
         const flag = this.root.onMouseDown(event);
-        if (!flag && !event.ctrlKey) {
+        if (!flag) {
             this.selectContainer.clear();
         }
         return flag;
-    } // Function onMouseDown()
+    }
 
     /**
      * 鼠标移动事件
      *
-     * @param   event   保存事件参数
-     * @return  boolean
+     * @param event   保存事件参数
+     * @return 是否处理事件
      */
     onMouseMove(event: SMouseEvent): boolean {
         if (this.grabItem != null) {
@@ -201,13 +196,13 @@ export class SGraphScene {
             );
         }
         return this.root.onMouseMove(event);
-    } // Function onMouseMove()
+    }
 
     /**
      * 释放鼠标事件
      *
-     * @param   event       保存事件参数
-     * @return  boolean
+     * @param event       保存事件参数
+     * @return 是否处理事件
      */
     onMouseUp(event: SMouseEvent): boolean {
         if (this.grabItem != null) {
@@ -216,12 +211,13 @@ export class SGraphScene {
             );
         }
         return this.root.onMouseUp(event);
-    } // Function onMouseUp()
+    }
 
     /**
      * 上下文菜单事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
+     * @return 是否处理事件
      */
     onContextMenu(event: SMouseEvent): boolean {
         if (this.grabItem != null) {
@@ -231,49 +227,38 @@ export class SGraphScene {
         }
 
         return this.root.onContextMenu(event);
-    } // Function onContextMenu()
+    }
 
     /**
      * 按键按下事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     onKeyDown(event: KeyboardEvent): void {
         if (this.grabItem != null) {
             return this.grabItem.onKeyDown(event);
         }
         return this.root.onKeyDown(event);
-    } // Function onKeyDown()
-
-    // /**
-    //  * 按键press事件
-    //  *
-    //  * @param   event       事件参数
-    //  */
-    // onKeyPress(event: KeyboardEvent): void {
-    //     if (this.grabItem != null) {
-    //         this.grabItem.onKeyPress(event);
-    //     }
-    // } // Function onKeyPress()
+    }
 
     /**
      * 按键松开事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     onKeyUp(event: KeyboardEvent): void {
         if (this.grabItem != null) {
             return this.grabItem.onKeyUp(event);
         }
         return this.root.onKeyUp(event);
-    } // Function onKeyUp()
+    }
 
     /**
-     * 转换场景事件坐标到指定Item坐标事件
+     * 转换场景事件坐标到指定 Item 坐标事件
      *
-     * @param   item        指定的item对象
-     * @param   event       场景事件
-     * @return  {}
+     * @param item        指定的 item 对象
+     * @param event       场景事件
+     * @return 转换场景事件坐标到指定 Item 坐标事件
      */
     private toGrabItemMotionEvent(
         item: SGraphItem,
@@ -293,5 +278,5 @@ export class SGraphScene {
         se.x = p.x;
         se.y = p.y;
         return se;
-    } // Function toGrabItemMotionEvent()
-} // Class SGraphScene
+    }
+}

+ 135 - 91
saga-web-graph/src/SGraphView.ts

@@ -1,4 +1,4 @@
-import { SMouseEvent, SNetUtil } from "@saga-web/base/lib";
+import { SMouseEvent, SNetUtil } from "@saga-web/base";
 import {
     SCanvasPaintEngine,
     SCanvasView,
@@ -6,23 +6,23 @@ import {
     SPoint,
     SRect,
     SSvgPaintEngine
-} from "@saga-web/draw/lib";
+} from "@saga-web/draw";
 import { SGraphScene } from "./SGraphScene";
 import { SGraphItem } from "./SGraphItem";
 import { v1 as uuidv1 } from "uuid";
 import { SColor } from "@saga-web/draw";
 
 /**
- * Graphy图形引擎视图类
+ * Graph 图形引擎视图类
  *
- * @author  庞利祥(sybotan@126.com)
+ * @author 庞利祥 <sybotan@126.com>
  */
 export class SGraphView extends SCanvasView {
     /** 场景对象 */
     private _scene: SGraphScene | null = null;
     get scene(): SGraphScene | null {
         return this._scene;
-    } // Get scene
+    }
     set scene(v: SGraphScene | null) {
         if (this._scene != null) {
             this._scene.view = null;
@@ -32,27 +32,27 @@ export class SGraphView extends SCanvasView {
             this._scene.view = this;
         }
         this.update();
-    } // Set scene
+    }
     /** 背景色 */
     backgroundColor: SColor = SColor.Transparent;
-    /** 旋转角度    */
+    /** 旋转角度 */
     rotate: number = 0;
 
     /**
      * 构造函数
      *
-     * @param   id      画布对象ID
+     * @param id      画布对象 ID
      */
     constructor(id: string) {
         super(id);
-    } // Function constructor()
+    }
 
     /**
-     * 保存场景SVG文件
+     * 保存场景 SVG 文件
      *
-     * @param   name    文件名
-     * @param   width   svg宽度
-     * @param   height  svg高度
+     * @param name    文件名
+     * @param width   svg 宽度
+     * @param height  svg 高度
      */
     saveSceneSvg(name: string, width: number, height: number): void {
         let url = URL.createObjectURL(
@@ -61,14 +61,14 @@ export class SGraphView extends SCanvasView {
             })
         );
         SNetUtil.downLoad(name, url);
-    } // Function saveSceneSvg()
+    }
 
     /**
-     * 场景SVG图形的数据
+     * 场景 SVG 图形的数据
      *
-     * @param   width   svg宽度
-     * @param   height  svg高度
-     * @return  URL地址
+     * @param width   svg 宽度
+     * @param height  svg 高度
+     * @return URL 地址
      */
     sceneSvgData(width: number, height: number): string {
         if (null == this.scene) {
@@ -93,7 +93,7 @@ export class SGraphView extends SCanvasView {
         this.origin.y = y0;
 
         return engine.toSvg();
-    } // Function saveSvg()
+    }
 
     /**
      * 适配视图到视图
@@ -106,7 +106,7 @@ export class SGraphView extends SCanvasView {
         // 场景中无对象
         let rect = this.scene.allItemRect();
         this.fitRectToSize(this.width, this.height, rect);
-    } // Function FitView()
+    }
 
     /**
      * 适配选中的对象在视图中可见
@@ -119,7 +119,7 @@ export class SGraphView extends SCanvasView {
         // 场景中无对象
         let rect = this.scene.selectedItemRect();
         this.fitRectToSize(this.width, this.height, rect);
-    } // Function fitSelectedToSize()
+    }
 
     /**
      * 适配任意对象在视图中可见
@@ -130,7 +130,7 @@ export class SGraphView extends SCanvasView {
         }
         let rect: SRect | null = null;
 
-        // 依次取item列中的所有item。将所有item的边界做并焦处理。
+        // 依次取 item 列中的所有 item。将所有 item 的边界做并焦处理。
         for (let item of itemList) {
             if (rect == null) {
                 rect = item.boundingRect().translated(item.pos.x, item.pos.y);
@@ -142,35 +142,35 @@ export class SGraphView extends SCanvasView {
         }
         // 场景中无对象
         this.fitRectToSize(this.width, this.height, rect);
-    } // Function fitItemToView()
+    }
 
     /**
-     * 将场景中的xy坐标转换成视图坐标。
+     * 将场景中的 x, y 坐标转换成视图坐标。
      *
-     * @param   x       场景中的横坐标
-     * @param   y       场景中的纵坐标
-     * @return  视图坐标
+     * @param x     场景中的横坐标
+     * @param y     场景中的纵坐标
+     * @return 视图坐标
      */
     mapFromScene(x: number, y: number): SPoint;
 
     /**
-     * 将场景中的xy坐标转换成视图坐标。
+     * 将场景中的 x, y 坐标转换成视图坐标。
      *
-     * @param   pos      场景中的坐标
-     * @return  视图坐标
+     * @param pos   场景中的坐标
+     * @return 视图坐标
      */
     mapFromScene(pos: SPoint): SPoint;
 
     /**
-     * 将场景中的xy坐标转换成视图坐标(重载实现)。
+     * 将场景中的 x, y 坐标转换成视图坐标(重载实现)。
      *
-     * @param   x       场景中的横坐标
-     * @param   y       场景中的纵坐标
-     * @return  视图坐标
+     * @param x     场景中的横坐标
+     * @param y     场景中的纵坐标
+     * @return 视图坐标
      */
     mapFromScene(x: number | SPoint, y?: number): SPoint {
         if (x instanceof SPoint) {
-            // 如果传入的是SPoint对象
+            // 如果传入的是 SPoint 对象
             return new SPoint(
                 x.x * this.scale + this.origin.x,
                 x.y * this.scale + this.origin.y
@@ -182,35 +182,35 @@ export class SGraphView extends SCanvasView {
             x * this.scale + this.origin.x,
             (y == undefined ? 0 : y) * this.scale + this.origin.y
         );
-    } // Function mapFromScene()
+    }
 
     /**
-     * 将i视图的xy坐标转换成场景坐标。
+     * 将视图的 x, y 坐标转换成场景坐标。
      *
-     * @param   x       视图横坐标
-     * @param   y       视图纵坐标
-     * @return  场景坐标
+     * @param x     视图横坐标
+     * @param y     视图纵坐标
+     * @return 场景坐标
      */
     mapToScene(x: number, y: number): SPoint;
 
     /**
-     * 将i视图的xy坐标转换成场景坐标。
+     * 将视图的 x, y 坐标转换成场景坐标。
      *
-     * @param   pos     视图坐标
-     * @return  场景坐标
+     * @param pos     视图坐标
+     * @return 场景坐标
      */
     mapToScene(pos: SPoint): SPoint;
 
     /**
-     * 将i视图的xy坐标转换成场景坐标。(不推荐在外部调用)
+     * 将视图的 x, y 坐标转换成场景坐标。(不推荐在外部调用)
      *
-     * @param   x       视图的横坐标/或SPoint对象
-     * @param   y       视图的纵坐标
-     * @return  场景坐标
+     * @param x       视图的横坐标或 SPoint 对象
+     * @param y       视图的纵坐标
+     * @return 场景坐标
      */
     mapToScene(x: number | SPoint, y?: number): SPoint {
         if (x instanceof SPoint) {
-            // 如果传入的是SPoint对象
+            // 如果传入的是 SPoint 对象
             return new SPoint(
                 (x.x - this.origin.x) / this.scale,
                 (x.y - this.origin.y) / this.scale
@@ -221,23 +221,71 @@ export class SGraphView extends SCanvasView {
             (x - this.origin.x) / this.scale,
             ((y == undefined ? 0 : y) - this.origin.y) / this.scale
         );
-    } // Function mapToScene()
+    }
 
     /**
-     * 保存图像
+     * 保存指定大小图像,并且适配到中央而不影响原图
      *
-     * @param   name    名称
-     * @param   type    图像类型
-     * @param   width   要保存图形的宽
-     * @param   height  要保存图形的高
+     * @param name    名称
+     * @param type    图像类型
+     * @param width   要保存图形的宽
+     * @param height  要保存图形的高
+     * @param bg      生成图的背景色
      */
     saveImageSize(
         name: string,
         type: string,
         width: number,
-        height: number
+        height: number,
+        bg: string = "#ffffff"
     ): void {
         const can = document.createElement("CANVAS") as HTMLCanvasElement;
+        let vi: any = this.generateView(can, width, height, bg);
+        vi.saveImage(name, type);
+        // @ts-ignore
+        this.scene.view = this;
+        can.remove();
+        vi = null;
+    }
+
+    /**
+     * 保存指定大小图像,并且适配到中央而不影响原图所使用的图像的 URL
+     *
+     * @param type    图像类型
+     * @param width   要保存图形的宽
+     * @param height  要保存图形的高
+     * @param bg      生成图的背景色
+     * @return 图像的 URL
+     */
+    imageSizeUrl(
+        type: string,
+        width: number,
+        height: number,
+        bg: string = "#FFFFFF"
+    ): string {
+        const can = document.createElement("CANVAS") as HTMLCanvasElement;
+        let vi: any = this.generateView(can, width, height, bg);
+        const str = vi.canvasView.toDataURL(`image/${type}`);
+        can.remove();
+        vi = null;
+        return str;
+    }
+
+    /**
+     * 生成新的view
+     *
+     * @param can       canvas dom
+     * @param width     要保存图形的宽
+     * @param height    要保存图形的高
+     * @param bg        生成图的背景色
+     * @return 图像的 URL
+     */
+    private generateView(
+        can: HTMLCanvasElement,
+        width: number,
+        height: number,
+        bg: string = "#FFFFFF"
+    ): SGraphView {
         can.width = width;
         can.height = height;
         can.id = uuidv1();
@@ -250,20 +298,15 @@ export class SGraphView extends SCanvasView {
         let vi = new SGraphView(can.id);
         vi.scene = this.scene;
         vi.fitSceneToView();
-        vi.backgroundColor = new SColor("#FFFFFF");
+        vi.backgroundColor = new SColor(bg);
         vi.onDraw(painter);
-        vi.saveImage(name, type);
-        // @ts-ignore
-        this.scene.view = this;
-        can.remove();
-        // @ts-ignore
-        vi = null;
-    } // Function saveImageSize()
+        return vi;
+    }
 
     /**
      * 绘制视图
      *
-     * @param   painter     painter对象
+     * @param painter       绘制对象
      */
     protected onDraw(painter: SPainter): void {
         painter.save();
@@ -291,45 +334,45 @@ export class SGraphView extends SCanvasView {
         painter.save();
         this.drawForeground(painter);
         painter.restore();
-    } // Function onDraw();
+    }
 
     /**
      * 绘制场景背景
      *
-     * @param   painter     painter对象
+     * @param painter     绘制对象
      */
     protected drawBackground(painter: SPainter): void {
         painter.brush.color = this.backgroundColor;
         painter.pen.color = SColor.Transparent;
         painter.drawRect(0, 0, this.width, this.height);
         // DO NOTHING
-    } // Function drawBackground()
+    }
 
     /**
      * 绘制场景前景
      *
-     * @param   painter     painter对象
+     * @param painter     绘制对象
      */
     protected drawForeground(painter: SPainter): void {
         // DO NOTHING
-    } // Function drawForeground()
+    }
 
     /**
      * 鼠标双击事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     protected onDoubleClick(event: MouseEvent): void {
         if (this.scene != null) {
             let ce = this.toSceneMotionEvent(event);
             this.scene.onDoubleClick(ce);
         }
-    } // Function onClick()
+    }
 
     /**
      * 鼠标按下事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     protected onMouseDown(event: MouseEvent): void {
         super.onMouseDown(event);
@@ -337,12 +380,12 @@ export class SGraphView extends SCanvasView {
             let ce = this.toSceneMotionEvent(event);
             this.scene.onMouseDown(ce);
         }
-    } // Function onClick()
+    }
 
     /**
      * 鼠标移动事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     protected onMouseMove(event: MouseEvent): void {
         super.onMouseMove(event);
@@ -350,12 +393,12 @@ export class SGraphView extends SCanvasView {
             let ce = this.toSceneMotionEvent(event);
             this.scene.onMouseMove(ce);
         }
-    } // Function onClick()
+    }
 
     /**
      * 鼠标松开事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     protected onMouseUp(event: MouseEvent): void {
         super.onMouseUp(event);
@@ -363,48 +406,48 @@ export class SGraphView extends SCanvasView {
             let ce = this.toSceneMotionEvent(event);
             this.scene.onMouseUp(ce);
         }
-    } // Function onClick()
+    }
 
     /**
      * 上下文菜单事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     protected onContextMenu(event: MouseEvent): void {
         if (this.scene != null) {
             let ce = this.toSceneMotionEvent(event);
             this.scene.onContextMenu(ce);
         }
-    } // Function onContextMenu()
+    }
 
     /**
      * 按键按下事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     protected onKeyDown(event: KeyboardEvent): void {
         if (this.scene != null) {
             this.scene.onKeyDown(event);
         }
-    } // Function onKeyDown()
+    }
 
     /**
      * 按键松开事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
      */
     protected onKeyUp(event: KeyboardEvent): void {
         if (this.scene != null) {
             this.scene.onKeyUp(event);
         }
-    } // Function onKeyUp()
+    }
 
     /**
      * 适配场景在视图中可见
      *
-     * @param   width       宽度
-     * @param   height      高度
-     * @param   rect        对象的矩阵大小
+     * @param width       宽度
+     * @param height      高度
+     * @param rect        对象的矩阵大小
      */
     private fitRectToSize(
         width: number,
@@ -422,12 +465,13 @@ export class SGraphView extends SCanvasView {
         let center = rect.center();
         this.origin.x = width / 2.0 - center.x * this.scale;
         this.origin.y = height / 2.0 - center.y * this.scale;
-    } // Function fitRectToSize()
+    }
 
     /**
-     * MouseEvent事件转换成场景SMouseEvent事件
+     * MouseEvent 事件转换成场景 SMouseEvent 事件
      *
-     * @param   event       事件参数
+     * @param event       事件参数
+     * @return MouseEvent 事件转换成场景 SMouseEvent 事件
      */
     private toSceneMotionEvent(event: MouseEvent): SMouseEvent {
         let se = new SMouseEvent(event);
@@ -442,5 +486,5 @@ export class SGraphView extends SCanvasView {
         se.x = mp.x;
         se.y = mp.y;
         return se;
-    } // Function toSceneMotionEvent()
-} // Class SGraphView
+    }
+}

+ 1 - 0
saga-web-graph/src/items/SImageItem.ts

@@ -223,6 +223,7 @@ export class SImageItem extends SObjectItem {
      */
     onMouseDown(event: SMouseEvent): boolean {
         this.$emit("click", event);
+        super.onMouseDown(event);
         return true;
     }