|
@@ -1,353 +1,15 @@
|
|
|
<template>
|
|
|
<div>
|
|
|
- <el-button @click="show">展示</el-button>
|
|
|
<el-button @click="create">创建</el-button>
|
|
|
- <el-button @click="edit">编辑</el-button>
|
|
|
+ <el-button @click="undo">undo</el-button>
|
|
|
+ <el-button @click="redo">redo</el-button>
|
|
|
<canvas id="editLine" width="740" height="400" tabindex="0" />
|
|
|
</div>
|
|
|
</template>
|
|
|
-<script lang='ts'>
|
|
|
- import {SGraphItem, SGraphScene, SGraphView} from "@saga-web/graph/";
|
|
|
- import {SMouseEvent} from "@saga-web/base/";
|
|
|
- import {SColor, SLine, SPainter, SPoint, SRect} from "@saga-web/draw";
|
|
|
- import {SRelationState} from "@saga-web/big/lib/enums/SRelationState";
|
|
|
- import {SMathUtil} from "@saga-web/big/lib/utils/SMathUtil";
|
|
|
-
|
|
|
- /**
|
|
|
- * 直线item
|
|
|
- *
|
|
|
- * @author 张宇(taohuzy@163.com)
|
|
|
- * */
|
|
|
-
|
|
|
- class SLineItem extends SGraphItem {
|
|
|
- /** 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 {
|
|
|
- return this._status;
|
|
|
- }
|
|
|
- set status(v: SRelationState) {
|
|
|
- this._status = v;
|
|
|
- this.update();
|
|
|
- }
|
|
|
-
|
|
|
- /** 线条颜色 */
|
|
|
- _strokeColor: string = "#000000";
|
|
|
- get strokeColor(): string {
|
|
|
- return this._strokeColor;
|
|
|
- }
|
|
|
- set strokeColor(v: string) {
|
|
|
- this._strokeColor = v;
|
|
|
- this.update();
|
|
|
- }
|
|
|
-
|
|
|
- /** 填充色 */
|
|
|
- _fillColor: string = "#2196f3";
|
|
|
- get fillColor(): string {
|
|
|
- return this._fillColor;
|
|
|
- }
|
|
|
- set fillColor(v: string) {
|
|
|
- this._fillColor = v;
|
|
|
- this.update();
|
|
|
- }
|
|
|
-
|
|
|
- /** 线条宽度 */
|
|
|
- _lineWidth: number = 1;
|
|
|
- get lineWidth(): number {
|
|
|
- return this._lineWidth;
|
|
|
- }
|
|
|
- set lineWidth(v: number) {
|
|
|
- this._lineWidth = v;
|
|
|
- this.update();
|
|
|
- }
|
|
|
-
|
|
|
- /** 拖动灵敏度 */
|
|
|
- dis: number = 10;
|
|
|
-
|
|
|
- /** 拖动灵敏度 */
|
|
|
- sceneDis: number = 10;
|
|
|
-
|
|
|
- /** 当前点索引 */
|
|
|
- curIndex: number = -1;
|
|
|
-
|
|
|
- /**
|
|
|
- * 构造函数
|
|
|
- *
|
|
|
- * @param parent 父级
|
|
|
- * @param line 坐标集合
|
|
|
- * */
|
|
|
- constructor(parent: SGraphItem | null, line: SPoint[]);
|
|
|
-
|
|
|
- /**
|
|
|
- * 构造函数
|
|
|
- *
|
|
|
- * @param parent 父级
|
|
|
- * @param point 第一个点坐标
|
|
|
- * */
|
|
|
- constructor(parent: SGraphItem | null, point: SPoint);
|
|
|
-
|
|
|
- /**
|
|
|
- * 构造函数
|
|
|
- *
|
|
|
- * @param parent 父级
|
|
|
- * @param l 坐标集合|第一个点坐标
|
|
|
- * */
|
|
|
- constructor(parent: SGraphItem | null, l: SPoint | SPoint[]) {
|
|
|
- super(parent);
|
|
|
- if (l instanceof SPoint) {
|
|
|
- this.line.push(l);
|
|
|
- } else {
|
|
|
- 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) {
|
|
|
- if (this.scene) {
|
|
|
- this.scene.grabItem = this;
|
|
|
- }
|
|
|
- this.status = SRelationState.Edit;
|
|
|
- } else if (this.status = SRelationState.Edit) {
|
|
|
- this.status = SRelationState.Normal;
|
|
|
- }
|
|
|
- this.update();
|
|
|
- }
|
|
|
- return true;
|
|
|
- } // Function onDoubleClick()
|
|
|
-
|
|
|
- /**
|
|
|
- * 鼠标按下事件
|
|
|
- *
|
|
|
- * @param event 鼠标事件
|
|
|
- * @return 是否处理事件
|
|
|
- * */
|
|
|
- onMouseDown(event: SMouseEvent): boolean {
|
|
|
- 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");
|
|
|
- return true;
|
|
|
- } // Function onMouseDown()
|
|
|
-
|
|
|
- /**
|
|
|
- * 鼠标抬起事件
|
|
|
- *
|
|
|
- * @param event 事件参数
|
|
|
- * @return boolean
|
|
|
- */
|
|
|
- onMouseUp(event: SMouseEvent): boolean {
|
|
|
- if (this._status == SRelationState.Edit) {
|
|
|
- this.curIndex = -1;
|
|
|
- }
|
|
|
- return true;
|
|
|
- } // Function onMouseUp()
|
|
|
-
|
|
|
- /**
|
|
|
- * 鼠标移动事件
|
|
|
- *
|
|
|
- * @param event 鼠标事件
|
|
|
- * @return 是否处理事件
|
|
|
- * */
|
|
|
- onMouseMove(event: SMouseEvent): boolean {
|
|
|
- if (this.status == SRelationState.Create) {
|
|
|
- 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;
|
|
|
- }
|
|
|
- } else {
|
|
|
- return super.onMouseMove(event);
|
|
|
- }
|
|
|
- this._xyzListToSPointList(this.line);
|
|
|
- this.update();
|
|
|
- return true;
|
|
|
- } // Function onMouseMove()
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取点击点与Point[]中的点距离最近点
|
|
|
- *
|
|
|
- * @param p 鼠标点击点
|
|
|
- * */
|
|
|
- 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 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;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断点是否在区域内
|
|
|
- *
|
|
|
- * @param x
|
|
|
- * @param y
|
|
|
- * @return true-是
|
|
|
- */
|
|
|
- contains(x: number, y: number): boolean {
|
|
|
- if (this.line.length == 2) {
|
|
|
- let p = new SPoint(x, y);
|
|
|
- if (
|
|
|
- SMathUtil.pointToLine(p, new SLine(this.line[0], this.line[1])).MinDis <
|
|
|
- this.dis
|
|
|
- ) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- } // 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对象
|
|
|
- */
|
|
|
- onDraw(painter: SPainter): void {
|
|
|
- this.sceneDis = painter.toPx(this.dis);
|
|
|
- painter.pen.lineWidth = painter.toPx(this.lineWidth);
|
|
|
- painter.pen.color = new SColor(this.strokeColor);
|
|
|
- if (this.line.length == 2) {
|
|
|
- // 绘制外轮廓
|
|
|
- // painter.brush.color = SColor.Transparent;
|
|
|
- // painter.pen.color = new SColor("#128eee");
|
|
|
- // painter.drawRect(this.boundingRect());
|
|
|
-
|
|
|
- // 绘制直线
|
|
|
- painter.pen.color = new SColor(this.strokeColor);
|
|
|
- painter.drawLine(this.line[0], this.line[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));
|
|
|
- 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()
|
|
|
- } // Class SLineItem
|
|
|
+<script>
|
|
|
+ import { SGraphScene, SGraphView } from "@saga-web/graph/";
|
|
|
+ import { SItemStatus } from "@saga-web/big/lib/enums/SItemStatus";
|
|
|
+ import { SLineItem } from "@saga-web/big/lib";
|
|
|
|
|
|
export default {
|
|
|
data() {
|
|
@@ -356,37 +18,29 @@
|
|
|
view: null
|
|
|
};
|
|
|
},
|
|
|
- mounted(): void {
|
|
|
+ mounted() {
|
|
|
this.view = new SGraphView("editLine");
|
|
|
+ this.scene = new SGraphScene();
|
|
|
+ this.view.scene = this.scene;
|
|
|
},
|
|
|
methods: {
|
|
|
- show() {
|
|
|
- const scene = new SGraphScene();
|
|
|
- this.view.scene = scene;
|
|
|
- const line: SPoint[] = [new SPoint(100, 100), new SPoint(300, 300)];
|
|
|
- const lineItem = new SLineItem(null, line);
|
|
|
- lineItem.status = SRelationState.Normal;
|
|
|
- scene.addItem(lineItem);
|
|
|
- this.view.fitSceneToView();
|
|
|
- },
|
|
|
create() {
|
|
|
- const scene = new SGraphScene();
|
|
|
- this.view.scene = scene;
|
|
|
+ this.scene.root.children = [];
|
|
|
const lineItem = new SLineItem(null, [] );
|
|
|
- lineItem.status = SRelationState.Create;
|
|
|
- scene.addItem(lineItem);
|
|
|
- scene.grabItem = lineItem;
|
|
|
+ lineItem.status = SItemStatus.Create;
|
|
|
+ this.scene.addItem(lineItem);
|
|
|
+ this.scene.grabItem = lineItem;
|
|
|
this.view.fitSceneToView();
|
|
|
},
|
|
|
- edit() {
|
|
|
- const scene = new SGraphScene();
|
|
|
- this.view.scene = scene;
|
|
|
- const line: SPoint[] = [new SPoint(100, 100), new SPoint(300, 300)];
|
|
|
- const lineItem = new SLineItem(null, line);
|
|
|
- lineItem.status = SRelationState.Edit;
|
|
|
- scene.addItem(lineItem);
|
|
|
- scene.grabItem = lineItem;
|
|
|
- this.view.fitSceneToView();
|
|
|
+ undo(){
|
|
|
+ if(this.scene.grabItem) {
|
|
|
+ this.scene.grabItem.undo();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ redo(){
|
|
|
+ if(this.scene.grabItem) {
|
|
|
+ this.scene.grabItem.redo();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
};
|