|
@@ -0,0 +1,235 @@
|
|
|
+import { SMouseEvent } from "@persagy-web/base/lib";
|
|
|
+import { SMathUtil } from "@persagy-web/big/lib/utils/SMathUtil";
|
|
|
+import { SPoint, SRect } from "@persagy-web/draw/lib";
|
|
|
+import { FloorScene } from "./FloorScene";
|
|
|
+import { HighlightItem } from "./HighlightItem";
|
|
|
+import { ShadeItem } from "./ShadeItem";
|
|
|
+
|
|
|
+export class DivideFloorScene extends FloorScene {
|
|
|
+ /** 划分item */
|
|
|
+ cutItem: ShadeItem | null = null;
|
|
|
+ /** 是否开启切分 */
|
|
|
+ isCutting: boolean = false;
|
|
|
+
|
|
|
+ /** 是否开启吸附 */
|
|
|
+ private _isAbsorbing: boolean = true;
|
|
|
+ get isAbsorbing(): boolean {
|
|
|
+ return this._isAbsorbing;
|
|
|
+ } // Get isAbsorbing
|
|
|
+ set isAbsorbing(v: boolean) {
|
|
|
+ this._isAbsorbing = v;
|
|
|
+ } // Set isAbsorbing
|
|
|
+
|
|
|
+ /** 高亮item */
|
|
|
+ highLight: HighlightItem | null = null;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清除划分区域
|
|
|
+ */
|
|
|
+ clearCut(): void {
|
|
|
+ if (this.cutItem) {
|
|
|
+ this.grabItem = null;
|
|
|
+ this.removeItem(this.cutItem);
|
|
|
+ this.cutItem = null;
|
|
|
+ this.isCutting = false;
|
|
|
+ this.view && this.view.update();
|
|
|
+ }
|
|
|
+ } // Function clearCut()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 鼠标按下事件
|
|
|
+ *
|
|
|
+ * @param event 保存事件参数
|
|
|
+ * @return boolean
|
|
|
+ */
|
|
|
+ onMouseDown(event: SMouseEvent): boolean {
|
|
|
+ if (event.buttons == 1) {
|
|
|
+ if (this.isCutting) {
|
|
|
+ // 判断是否开启吸附,并且有吸附的点
|
|
|
+ if (
|
|
|
+ this.isAbsorbing &&
|
|
|
+ this.highLight &&
|
|
|
+ this.highLight.visible
|
|
|
+ ) {
|
|
|
+ event.x = this.highLight.point.x;
|
|
|
+ event.y = this.highLight.point.y;
|
|
|
+ }
|
|
|
+ if (this.cutItem) {
|
|
|
+ return this.cutItem.onMouseDown(event);
|
|
|
+ } else {
|
|
|
+ let point = new SPoint(event.x, event.y);
|
|
|
+ let cut = new ShadeItem(null, point);
|
|
|
+ this.addItem(cut);
|
|
|
+ this.cutItem = cut;
|
|
|
+ this.grabItem = cut;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return super.onMouseDown(event)
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 吸附空间
|
|
|
+ *
|
|
|
+ * @param event 鼠标事件对象
|
|
|
+ */
|
|
|
+ onMouseMove(event: SMouseEvent): boolean {
|
|
|
+ super.onMouseMove(event);
|
|
|
+ if (this.isAbsorbing) {
|
|
|
+ if (!this.highLight) {
|
|
|
+ this.highLight = new HighlightItem(null);
|
|
|
+ this.addItem(this.highLight);
|
|
|
+ }
|
|
|
+ this.highLight.visible = false;
|
|
|
+ // if (!this.absorbShade(event)) {
|
|
|
+ this.absorbSpace(event);
|
|
|
+ // }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ } // Function onMouseMove()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 吸附空间
|
|
|
+ *
|
|
|
+ * @param event 鼠标事件对象
|
|
|
+ * @return boolean 是否找到吸附的对象
|
|
|
+ */
|
|
|
+ absorbSpace(event: SMouseEvent): boolean {
|
|
|
+ if (!this.highLight) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ let absorbLen = 1000;
|
|
|
+ if (this.view) {
|
|
|
+ absorbLen = 10 / this.view.scale;
|
|
|
+ }
|
|
|
+ let P = this.absorbSpacePoint(event, absorbLen);
|
|
|
+ if (P.Point) {
|
|
|
+ this.highLight.distance = P.MinDis;
|
|
|
+ this.highLight.point = new SPoint(P.Point.X, -P.Point.Y);
|
|
|
+ this.highLight.visible = true;
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ let L = this.absorbSpaceLine(event, absorbLen);
|
|
|
+ if (L.Line && L.Point) {
|
|
|
+ this.highLight.distance = L.MinDis;
|
|
|
+ this.highLight.point = L.Point;
|
|
|
+ this.highLight.line = L.Line;
|
|
|
+ this.highLight.visible = true;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } // Function absorbSpace()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 吸附空间点
|
|
|
+ *
|
|
|
+ * @param event 鼠标事件对象
|
|
|
+ * @param absorbLen 吸附距离
|
|
|
+ * @return MinDis 吸附的点
|
|
|
+ */
|
|
|
+ absorbSpacePoint(event: SMouseEvent, absorbLen: number): any {
|
|
|
+ let minPointDis = Number.MAX_SAFE_INTEGER;
|
|
|
+ let Point;
|
|
|
+ this.spaceList.map((space): void => {
|
|
|
+ if (
|
|
|
+ DivideFloorScene.isPointInAbsorbArea(
|
|
|
+ new SPoint(event.x, event.y),
|
|
|
+ space.minX,
|
|
|
+ space.maxX,
|
|
|
+ space.minY,
|
|
|
+ space.maxY
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ space.data.OutLine.forEach((item): void => {
|
|
|
+ let minDis = SMathUtil.getMinDisPoint(
|
|
|
+ new SPoint(event.x, event.y),
|
|
|
+ item
|
|
|
+ );
|
|
|
+ if (
|
|
|
+ minDis &&
|
|
|
+ minDis.MinDis < absorbLen &&
|
|
|
+ minDis.MinDis < minPointDis
|
|
|
+ ) {
|
|
|
+ minPointDis = minDis.MinDis;
|
|
|
+ Point = minDis.Point;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ MinDis: minPointDis,
|
|
|
+ Point: Point
|
|
|
+ };
|
|
|
+ } // Function absorbSpacePoint()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 点是否在吸附区域内
|
|
|
+ *
|
|
|
+ * @param p 要判断的点
|
|
|
+ * @param minX 空间区域
|
|
|
+ * @param minY 空间区域
|
|
|
+ * @param maxX 空间区域
|
|
|
+ * @param maxY 空间区域
|
|
|
+ */
|
|
|
+ static isPointInAbsorbArea(
|
|
|
+ p: SPoint,
|
|
|
+ minX: number,
|
|
|
+ maxX: number,
|
|
|
+ minY: number,
|
|
|
+ maxY: number
|
|
|
+ ): boolean {
|
|
|
+ let rect = new SRect(
|
|
|
+ minX - 1000,
|
|
|
+ minY - 1000,
|
|
|
+ maxX - minX + 2000,
|
|
|
+ maxY - minY + 2000
|
|
|
+ );
|
|
|
+ return rect.contains(p.x, p.y);
|
|
|
+ } // Function isPointInAbsorbArea()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 吸附空间线
|
|
|
+ *
|
|
|
+ * @param event 鼠标事件对象
|
|
|
+ * @param absorbLen 吸附距离
|
|
|
+ * @return PointToLine 吸附的线
|
|
|
+ */
|
|
|
+ absorbSpaceLine(event: SMouseEvent, absorbLen: number): any {
|
|
|
+ let minPointDis = Number.MAX_SAFE_INTEGER;
|
|
|
+ let Point, Line;
|
|
|
+ this.spaceList.forEach((space): void => {
|
|
|
+ if (
|
|
|
+ DivideFloorScene.isPointInAbsorbArea(
|
|
|
+ new SPoint(event.x, event.y),
|
|
|
+ space.minX,
|
|
|
+ space.maxX,
|
|
|
+ space.minY,
|
|
|
+ space.maxY
|
|
|
+ )
|
|
|
+ ) {
|
|
|
+ space.data.OutLine.forEach((item): void => {
|
|
|
+ let minDisLine = SMathUtil.getMinDisLine(
|
|
|
+ new SPoint(event.x, event.y),
|
|
|
+ item
|
|
|
+ );
|
|
|
+ if (
|
|
|
+ minDisLine &&
|
|
|
+ minDisLine.MinDis < absorbLen &&
|
|
|
+ minDisLine.MinDis < minPointDis
|
|
|
+ ) {
|
|
|
+ minPointDis = minDisLine.MinDis;
|
|
|
+ Point = minDisLine.Point;
|
|
|
+ Line = minDisLine.Line;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ MinDis: minPointDis,
|
|
|
+ Point: Point,
|
|
|
+ Line: Line
|
|
|
+ };
|
|
|
+ } // Function absorbSpaceLine()
|
|
|
+}
|