Преглед на файлове

增加解析底图为图片的方法

haojianlong преди 4 години
родител
ревизия
3954590d8b
променени са 8 файла, в които са добавени 335 реда и са изтрити 3 реда
  1. 1 1
      package.json
  2. 17 0
      src/FloorScene.ts
  3. 13 0
      src/enums/SImageShowType.ts
  4. 11 0
      src/enums/STextOrigin.ts
  5. 5 1
      src/index.ts
  6. 231 0
      src/items/SImageItem.ts
  7. 56 0
      src/items/SObjectItem.ts
  8. 1 1
      tsconfig.json

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
     "name": "@saga-web/cad-engine",
-    "version": "2.0.565",
+    "version": "2.0.566",
     "description": "上格云 CAD图形引擎。",
     "main": "lib/index.js",
     "types": "lib/index.d.js",

+ 17 - 0
src/FloorScene.ts

@@ -35,6 +35,8 @@ import { ColumnItem } from "./items/ColumnItem";
 import { VirtualWallItem } from "./items/VirtualWallItem";
 import { DoorItem } from "./items/DoorItem";
 import { WindowItem } from "./items/WindowItem";
+import {SImageItem} from "./items/SImageItem";
+import {SImageShowType} from "./enums/SImageShowType";
 
 /**
  * 楼层场景
@@ -225,6 +227,21 @@ export class FloorScene extends SGraphyScene {
     } // Function loadUrl()
 
     /**
+     *  获取底图压缩文件
+     *
+     * @param   url 请求数据文件路径
+     * @param   _fn 回调
+     */
+    loadImg(url: string, _fn: Function): void {
+        const imgItem = new SImageItem(null, url);
+        imgItem.showType = SImageShowType.AutoFit;
+        imgItem.connect("imgLoadOver", this, () => {
+            _fn(imgItem);
+        });
+        this.addItem(imgItem);
+    } // Function loadImg()
+
+    /**
      *  解压数据
      *
      *  @param  blob     文件

+ 13 - 0
src/enums/SImageShowType.ts

@@ -0,0 +1,13 @@
+/**
+ * 图片item展示方式
+ *
+ * @author  haojianlong
+ */
+export enum SImageShowType {
+    /** 铺满  */
+    Full,
+    /** 自适应 */
+    AutoFit,
+    /** 等比缩放 */
+    Equivalency
+} // Enum SImageShowType

+ 11 - 0
src/enums/STextOrigin.ts

@@ -0,0 +1,11 @@
+/**
+ * 文本原点位置
+ *
+ * @author  张宇
+ */
+export enum STextOrigin {
+  /** 左上点    */
+  LeftTop,
+  /** 中心点    */
+  Centrum,
+} // Enum STextOrigin

+ 5 - 1
src/index.ts

@@ -18,6 +18,8 @@ import { LikeSpaceItem } from "./items/LikeSpaceItem";
 import { RelationScene } from "./RelationScene";
 import { ZoneScene } from "./ZoneScene";
 import { Opt } from "./types/Opt";
+import { SImageShowType } from "./enums/SImageShowType";
+import { STextOrigin } from "./enums/STextOrigin";
 
 export {
     FloorScene,
@@ -42,5 +44,7 @@ export {
     HighlightItem,
     ShadeItem,
     RectSelectItem,
-    LikeSpaceItem
+    LikeSpaceItem,
+    SImageShowType,
+    STextOrigin
 };

+ 231 - 0
src/items/SImageItem.ts

@@ -0,0 +1,231 @@
+import { SPainter, SRect, SSize, SColor, SPoint } from "@saga-web/draw/lib";
+import { SImageShowType, STextOrigin } from "..";
+import { SObjectItem } from "./SObjectItem";
+import { SGraphyItem } from "@saga-web/graphy/lib";
+
+/**
+ * 图片item
+ *
+ * @author  张宇(taohuzy@163.com)
+ */
+export class SImageItem extends SObjectItem {
+    /** 图片dom */
+    img: CanvasImageSource | undefined;
+
+    /** 展示模式 */
+    private _showType: SImageShowType = SImageShowType.Full;
+    get showType(): SImageShowType {
+        return this._showType;
+    }
+    set showType(v: SImageShowType) {
+        this._showType = v;
+        this.computeImgSize();
+        this.update();
+    }
+
+    /** 边框色 */
+    private _strokeColor: SColor = SColor.Transparent;
+    get strokeColor(): SColor {
+        return this._strokeColor;
+    }
+    set strokeColor(v: SColor) {
+        this._strokeColor = v;
+        this.update();
+    }
+
+    /** 边框宽度 */
+    private _lineWidth: number = 1;
+    get lineWidth(): number {
+        return this._lineWidth;
+    }
+    set lineWidth(v: number) {
+        this._lineWidth = v;
+        this.update();
+    }
+
+    /** 原点位置    */
+    private _originPosition: STextOrigin = STextOrigin.LeftTop;
+    get originPosition(): STextOrigin {
+        return this._originPosition;
+    }
+    set originPosition(v: STextOrigin) {
+        this._originPosition = v;
+        this.update();
+    }
+
+    /** 图片加载是否完成 */
+    isLoadOver: boolean = false;
+
+    /** 图片的宽度 */
+    private imgWidth: number = this.width;
+
+    /** 图片的高度 */
+    private imgHeight: number = this.height;
+
+    /** 图片地址 */
+    private _url: string = "";
+    get url(): string {
+        return this._url;
+    }
+    set url(v: string) {
+        this._url = v;
+        this.img = new Image();
+        this.img.onload = (e): void => {
+            // @ts-ignore
+            const imgSrc = e.path[0].src;
+            if (this.isUrlIdentical(imgSrc)) {
+                this.isLoadOver = true;
+                this.computeImgSize();
+                this.$emit("imgLoadOver");
+                this.update();
+            }
+        };
+        this.img.onerror = (e): void => {
+            // @ts-ignore
+            const imgSrc = e.path[0].src;
+            if (this.isUrlIdentical(imgSrc)) {
+                this.isLoadOver = false;
+                this.$emit("imgLoadOver");
+                this.update();
+                console.log("加载图片错误!", e);
+            }
+        };
+        this.img.src = v;
+    }
+
+    /**
+     * 构造函数
+     *
+     * @param   parent      指向父Item
+     * @param   url         图片地址
+     */
+    constructor(parent: SGraphyItem | null, url?: string) {
+        super(parent);
+        if (url) this.url = url;
+    } // Constructor
+
+    /**
+     * 根据显示模式计算图片的宽高
+     */
+    computeImgSize(): void {
+        if (this.isLoadOver) {
+            // 要绘制图片的宽度
+            let width = 0;
+            // 要绘制图片的宽度
+            let height = 0;
+            // 图片item的宽高比
+            let itemAspectRatio: number = this.width / this.height;
+            // 原始图片的宽高比
+            let imgAspectRatio: number =
+                // @ts-ignore
+                (this.img.width as number) / (this.img.height as number);
+            // 原始图片的高宽比
+            let imgHwRatio: number =
+                // @ts-ignore
+                (this.img.height as number) / (this.img.width as number);
+            if (this.showType == SImageShowType.Full) {
+                width = this.width;
+                height = this.height;
+            } else if (this.showType == SImageShowType.Equivalency) {
+                if (itemAspectRatio > imgAspectRatio) {
+                    height = this.height;
+                    width = imgAspectRatio * height;
+                } else if (itemAspectRatio < imgAspectRatio) {
+                    width = this.width;
+                    height = width * imgHwRatio;
+                } else {
+                    width = this.width;
+                    height = this.height;
+                }
+            } else if (this.showType == SImageShowType.AutoFit) {
+                // @ts-ignore
+                this.width = this.img.width as number;
+                // @ts-ignore
+                this.height = this.img.height as number;
+                width = this.width;
+                height = this.height;
+            }
+            this.imgWidth = width;
+            this.imgHeight = height;
+            // 设置原点位置(默认左上角)
+            if (this.originPosition == STextOrigin.Centrum) {
+                this.origin = new SPoint(this.width / 2, this.height / 2);
+            }
+        }
+    } // Function computeImgSize()
+
+    /**
+     * 判断当前地址和回调地址是否相同
+     * @param   imgUrl      图片回调地址
+     *
+     */
+    private isUrlIdentical(imgUrl: string): boolean {
+        if (this.url.indexOf("://") == -1) {
+            const reg = /^\s*data:([a-z]+\/[a-z0-9-+.]+(;[a-z-]+=[a-z0-9-]+)?)?(;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i;
+            if (reg.test(this.url)) {
+                // url是base64地址
+                return this.url == imgUrl;
+            } else {
+                // url是相对地址
+                return this.url == this.GetUrlRelativePath(imgUrl);
+            }
+        } else {
+            // url是绝对地址
+            return this.url == imgUrl;
+        }
+    } // Function isUrlIdentical()
+
+    /**
+     * 截取绝对路径中的相对路径
+     * @param   url      绝对路径
+     *
+     */
+    private GetUrlRelativePath(url: string): string {
+        var arrUrl = url.split("//");
+        var start = arrUrl[1].indexOf("/");
+        var relUrl = arrUrl[1].substring(start);
+        return relUrl;
+    } // Function GetUrlRelativePath()
+
+    /**
+     * Item对象边界区域
+     *
+     * @return	SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            -this.origin.x,
+            -this.origin.y,
+            this.width,
+            this.height
+        );
+    } // Function boundingRect()
+
+    /**
+     * 宽高发发生变化
+     *
+     * @param   oldSize 改之前的大小
+     * @param   newSize 改之后大小
+     * */
+    protected onResize(oldSize: SSize, newSize: SSize): void {
+        this.computeImgSize();
+        this.update();
+    } // Function onResize()
+
+    /**
+     * Item绘制操作
+     *
+     * @param   painter      绘画类
+     */
+    onDraw(painter: SPainter): void {
+        painter.translate(-this.origin.x, -this.origin.y);
+        if (this.isLoadOver) {
+            // @ts-ignore
+            painter.drawImage(this.img, 0, 0, this.imgWidth, this.imgHeight);
+        }
+        // painter.pen.lineWidth = this.lineWidth;
+        // painter.pen.color = this.strokeColor;
+        // painter.brush.color = SColor.Transparent;
+        // painter.drawRect(0, 0, this.width, this.height);
+    } // Function onDraw()
+} // Class SImageItem

+ 56 - 0
src/items/SObjectItem.ts

@@ -0,0 +1,56 @@
+import { SPoint, SSize } from "@saga-web/draw/lib";
+import { SGraphyItem } from "@saga-web/graphy/lib";
+
+/**
+ * 对象item
+ *
+ * @author  郝建龙(1061851420@qq.com)
+ */
+export abstract class SObjectItem extends SGraphyItem {
+    /** 宽度  */
+    private _width: number = 64;
+    get width(): number {
+        return this._width;
+    }
+    set width(v: number) {
+        if (v > 0) {
+            if (v != this._width) {
+                let w = this._width;
+                this._width = v;
+                this.onResize(
+                    new SSize(w, this._height),
+                    new SSize(this._width, this._height)
+                );
+            }
+        }
+    }
+
+    /** 高度  */
+    private _height: number = 64;
+    get height(): number {
+        return this._height;
+    }
+    set height(v: number) {
+        if (v > 0) {
+            if (v != this._height) {
+                let h = this._height;
+                this._height = v;
+                this.onResize(
+                    new SSize(this._width, h),
+                    new SSize(this._width, this._height)
+                );
+            }
+        }
+    }
+
+    /** 原点  */
+    origin = new SPoint();
+
+    /**
+     * 宽高发发生变化
+     *
+     * @param   oldSize 改之前的大小
+     * @param   newSize 改之后大小
+     * */
+    protected onResize(oldSize: SSize, newSize: SSize) {} // Function onResize()
+} // Class SObjectItem

+ 1 - 1
tsconfig.json

@@ -1,7 +1,7 @@
 {
     "compilerOptions": {
         "target": "es2015",                         // Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'.
-        "module": "es2015",                         // Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.
+        "module": "es6",                         // Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.
         "outDir": "./lib",                          // 编译后生成的文件目录
         "strict": true,                             // 开启严格的类型检测
         "declaration": true,                        // 生成 `.d.ts` 文件