123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 |
- <template>
- <div>
- <el-button @click="show">展示</el-button>
- <el-button @click="create">创建</el-button>
- <el-button @click="edit">编辑</el-button>
- <canvas id="editPolygon" width="800" height="400" tabindex="0"/>
- </div>
- </template>
- <script lang='ts'>
- import { SGraphItem, SGraphScene, SGraphView } from "@persagy-web/graph/";
- import { SMouseEvent } from "@persagy-web/base/";
- import { SColor, SLine, SLineCapStyle, SPainter, SPoint, SRect } from "@persagy-web/draw";
- import { SRelationState } from "@persagy-web/big/lib/enums/SRelationState";
- import { SMathUtil } from "@persagy-web/big/lib/utils/SMathUtil";
- /**
- * 可编辑多边形示例
- *
- * @author 郝洁 <haojie@persagy.com>
- */
- export default {
- data() {
- return {
- scene: null,
- view: null
- };
- },
- /**
- * 页面挂载
- */
- mounted(): void {
- this.view = new SGraphView("editPolygon");
- },
- methods: {
- show() {
- const scene = new SGraphScene();
- this.view.scene = scene;
- const spolygonItem = new SPolygonItem(null);
- spolygonItem.setStatus = SRelationState.Normal;
- const PointList: SPoint[] = [
- new SPoint(0, 0),
- new SPoint(50, 0),
- new SPoint(50, 50),
- new SPoint(0, 50)
- ];
- spolygonItem.setPointList = PointList;
- scene.addItem(spolygonItem);
- this.view.fitSceneToView();
- },
- create() {
- const scene = new SGraphScene();
- this.view.scene = scene;
- const spolygonItem = new SPolygonItem(null);
- spolygonItem.setStatus = SRelationState.Create;
- scene.addItem(spolygonItem);
- scene.grabItem = spolygonItem;
- this.view.fitSceneToView();
- },
- edit() {
- const scene = new SGraphScene();
- this.view.scene = scene;
- const spolygonItem = new SPolygonItem(null);
- spolygonItem.setStatus = SRelationState.Edit;
- const PointList: SPoint[] = [
- new SPoint(0, 0),
- new SPoint(50, 0),
- new SPoint(50, 60),
- new SPoint(0, 50)
- ];
- spolygonItem.setPointList = PointList;
- scene.addItem(spolygonItem);
- scene.grabItem = spolygonItem;
- this.view.fitSceneToView();
- }
- }
- };
- /**
- * @author hanyaolong
- */
- class SPolygonItem 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;
- /** 轮廓线坐标 */
- private pointList: SPoint[] = [];
- // 获取当前状态
- get getPointList(): SPoint[] {
- return this.pointList;
- }
- // 编辑当前状态
- set setPointList(arr: SPoint[]) {
- this.pointList = arr;
- if (arr) {
- this._xyzListToSPointList(arr);
- }
- this.update();
- }
- /** 是否闭合 */
- closeFlag: boolean = false;
- // 当前状态 1:show 2 创建中,3 编辑中
- _status: number = SRelationState.Normal;
- // 获取当前状态
- get getStatus(): number {
- return this._status;
- }
- // 编辑当前状态
- set setStatus(value: number) {
- this._status = value;
- this.update();
- }
- /** 边框颜色 */
- borderColor: SColor = new SColor("#0091FF");
- /** 填充颜色 */
- brushColor: SColor = new SColor("#1EE887");
- /** border宽 只可输入像素宽*/
- borderLine: number = 4;
- /** 鼠标移动点 */
- private lastPoint = new SPoint();
- /** 当前鼠标获取顶点对应索引 */
- private curIndex: number = -1;
- /** 灵敏像素 */
- private len: number = 15;
- /** 场景像素 */
- private scenceLen: number = 15;
- /** 场景像素 */
- private isAlt: boolean = false;
- /**
- * 构造函数
- *
- * @param parent 指向父对象
- */
- constructor(parent: SGraphItem | null) {
- super(parent);
- }
- ///////////////以下为对pointList 数组的操作方法
- /**
- * 储存新的多边形顶点
- * @param x 点位得x坐标
- * @param y 点位得y坐标
- * @param i 储存所在索引
- * @return SPoint
- */
- insertPoint(x: number, y: number, i: number | null = null): SPoint {
- const point = new SPoint(x, y);
- if (i == null) {
- this.pointList.push(point);
- } else {
- this.pointList.splice(i, 0, point);
- }
- this.update();
- return point;
- }
- /**
- * 删除点位
- * @param i 删除点所在的索引
- * @return SPoint
- */
- deletePoint(i: number | null = null): SPoint | null | undefined {
- let point = null;
- if (i != null) {
- if (this.pointList.length - 1 >= i) {
- point = this.pointList[i];
- this.pointList.splice(i, 1);
- } else {
- point = null;
- }
- } else {
- point = this.pointList.pop();
- }
- this.update();
- return point;
- }
- /**
- * 多边形顶点的移动位置
- * @param x 点位得x坐标
- * @param y 点位得y坐标
- * @param i 点位得i坐标
- * @return SPoint
- */
- movePoint(x: number, y: number, i: number): SPoint | null | undefined {
- let point = null;
- if (this.pointList.length) {
- this.pointList[i].x = x;
- this.pointList[i].y = y;
- }
- point = this.pointList[i];
- return point;
- }
- /**
- * 打印出多边形数组
- * @return SPoint[]
- */
- PrintPointList(): SPoint[] {
- return this.pointList;
- }
- ///////////////////////////
- /**
- * xyz数据转换为SPoint格式函数;获取外接矩阵参数
- *
- * @param arr 外层传入的数据PointList
- */
- protected _xyzListToSPointList(arr: SPoint[]): void {
- if (arr.length) {
- this.pointList = arr.map(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;
- }
- return new SPoint(x, y);
- });
- } else {
- this.pointList = [];
- }
- }
- ////////////以下为三种状态下的绘制多边形方法
- /**
- * 展示状态 --绘制多边形数组
- * @param painter 绘制类
- * @param pointList 绘制多边形数组
- *
- */
- protected drawShowPolygon(painter: SPainter, pointList: SPoint[]): void {
- painter.pen.lineCapStyle = SLineCapStyle.Square;
- painter.pen.color = this.borderColor;
- painter.pen.lineWidth = painter.toPx(this.borderLine);
- painter.brush.color = this.brushColor;
- painter.drawPolygon([...pointList]);
- }
- /**
- *
- * 创建状态 --绘制多边形数组
- * @param painter 绘制类
- * @param pointList 绘制多边形数组
- *
- */
- protected drawCreatePolygon(painter: SPainter, pointList: SPoint[]): void {
- painter.pen.lineCapStyle = SLineCapStyle.Square;
- painter.pen.color = this.borderColor;
- painter.pen.lineWidth = painter.toPx(4);
- painter.drawPolyline(pointList);
- if (this.lastPoint) {
- painter.drawLine(pointList[pointList.length - 1], this.lastPoint);
- }
- painter.pen.color = SColor.Transparent;
- painter.brush.color = this.brushColor;
- painter.pen.lineWidth = painter.toPx(4);
- painter.drawPolygon([...pointList, this.lastPoint]);
- }
- /**
- *
- * 编辑状态 --绘制多边形数组
- *
- * @param painter 绘制类
- * @param pointList 绘制多边形数组
- *
- */
- protected drawEditPolygon(painter: SPainter, pointList: SPoint[]): void {
- // 展示多边形
- this.drawShowPolygon(painter, pointList);
- // 绘制顶点块
- pointList.forEach((item, index) => {
- painter.drawCircle(item.x, item.y, painter.toPx(8));
- });
- }
- ////////////////////////////////
- /**
- * 编辑状态操作多边形数组
- *
- * @param event 鼠标事件
- *
- *
- */
- protected editPolygonPoint(event: SMouseEvent): void {
- // 判断是否为删除状态 isAlt = true为删除状态
- if (this.isAlt) {
- // 1 判断是否点击在多边形顶点
- let lenIndex = -1; // 当前点击到的点位索引;
- let curenLen = this.scenceLen; // 当前的灵敏度
- this.pointList.forEach((item, index) => {
- let dis = SMathUtil.pointDistance(event.x, event.y, item.x, item.y);
- if (dis < curenLen) {
- curenLen = dis;
- lenIndex = index;
- }
- });
- // 若点击到,对该索引对应的点做删除
- if (lenIndex != -1) {
- if (this.pointList.length <= 3) {
- return;
- }
- this.deletePoint(lenIndex);
- }
- } else {
- // 1 判断是否点击在多边形顶点
- this.curIndex = -1;
- let lenIndex = -1; // 当前点击到的点位索引;
- let curenLen = this.scenceLen; // 当前的灵敏度
- this.pointList.forEach((item, index) => {
- let dis = SMathUtil.pointDistance(event.x, event.y, item.x, item.y);
- if (dis < curenLen) {
- curenLen = dis;
- lenIndex = index;
- }
- });
- this.curIndex = lenIndex;
- // 2判断是否点击在多边形得边上
- if (-1 == lenIndex) {
- let len = SMathUtil.pointToLine(
- new SPoint(event.x, event.y),
- new SLine(this.pointList[0], this.pointList[1])
- ),
- index = 0;
- if (this.pointList.length > 2) {
- for (let i = 1; i < this.pointList.length; i++) {
- let dis = SMathUtil.pointToLine(
- new SPoint(event.x, event.y),
- new SLine(this.pointList[i], this.pointList[i + 1])
- );
- if (i + 1 == this.pointList.length) {
- dis = SMathUtil.pointToLine(
- new SPoint(event.x, event.y),
- new SLine(this.pointList[i], this.pointList[0])
- );
- }
- if (dis.MinDis < len.MinDis) {
- len = dis;
- index = i;
- }
- }
- }
- // 如果再线上则为新增点
- if (len.Point) {
- if (len.MinDis <= this.scenceLen) {
- this.pointList.splice(index + 1, 0, len.Point);
- }
- }
- }
- // 刷新视图
- this.update();
- }
- }
- ///////////////////////////////以下为鼠标事件
- /**
- * 鼠标双击事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onDoubleClick(event: SMouseEvent): boolean {
- // 如果位show状态 双击改对象则需改为编辑状态
- if (SRelationState.Normal == this._status) {
- this._status = SRelationState.Edit;
- } else if (SRelationState.Edit == this._status) {
- this._status = SRelationState.Normal;
- }
- this.update();
- return true;
- } // Function onDoubleClick()
- /**
- * 键盘事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onKeyDown(event: KeyboardEvent): boolean {
- console.log(event);
- if (this._status == SRelationState.Normal) {
- return false;
- } else if (this._status == SRelationState.Create) {
- if (event.code == "Enter") {
- this._status = SRelationState.Normal;
- }
- } else if (this._status == SRelationState.Edit) {
- if (event.key == "Alt") {
- this.isAlt = true;
- }
- } else {
- }
- this.update();
- return true;
- } // Function onKeyDown()
- /**
- * 键盘键抬起事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onKeyUp(event: KeyboardEvent): boolean {
- if (this._status == SRelationState.Edit) {
- if (event.key == "Alt") {
- this.isAlt = false;
- }
- }
- this.update();
- return true;
- } // Function onKeyUp()
- /**
- * 鼠标按下事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onMouseDown(event: SMouseEvent): boolean {
- console.log("aaaaaa");
- // 如果状态为编辑状态则添加点
- if (this._status == SRelationState.Create) {
- // 新增顶点
- this.insertPoint(event.x, event.y);
- } else if (this._status == SRelationState.Edit) {
- // 对多边形数组做编辑操作
- this.editPolygonPoint(event);
- }
- return true;
- } // Function onMouseDown()
- /**
- * 鼠标移入事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onMouseEnter(event: SMouseEvent): boolean {
- return true;
- } // Function onMouseEnter()
- /**
- * 鼠标移出事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onMouseLeave(event: SMouseEvent): boolean {
- return true;
- } // Function onMouseLeave()
- /**
- * 鼠标移动事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onMouseMove(event: SMouseEvent): boolean {
- if (this._status == SRelationState.Create) {
- this.lastPoint.x = event.x;
- this.lastPoint.y = event.y;
- } else if (this._status == SRelationState.Edit) {
- if (-1 != this.curIndex) {
- this.pointList[this.curIndex].x = event.x;
- this.pointList[this.curIndex].y = event.y;
- }
- }
- this.update();
- return true;
- } // Function onMouseMove()
- /**
- * 鼠标抬起事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onMouseUp(event: SMouseEvent): boolean {
- if (this._status == SRelationState.Edit) {
- this.curIndex = -1;
- }
- return true;
- } // Function onMouseUp()
- /**
- * 适配事件
- *
- * @param event 事件参数
- * @return boolean
- */
- onResize(event: SMouseEvent): boolean {
- return true;
- } // Function onResize()
- /**
- * 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.scenceLen = painter.toPx(this.len);
- // 当状态为展示状态
- if (this._status == SRelationState.Normal) {
- // 闭合多边形
- this.drawShowPolygon(painter, this.pointList);
- } else if (this._status == SRelationState.Create) {
- // 创建状态
- this.drawCreatePolygon(painter, this.pointList);
- } else {
- // 编辑状态
- this.drawEditPolygon(painter, this.pointList);
- }
- } // Function onDraw()
- }
- </script>
|