|
@@ -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
|
|
|
+ }
|
|
|
+}
|