diff --git a/package-lock.json b/package-lock.json index 0eb480e..9c9cca4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12876,6 +12876,11 @@ "sha.js": "^2.4.8" } }, + "penner": { + "version": "0.1.3", + "resolved": "https://registry.npm.taobao.org/penner/download/penner-0.1.3.tgz", + "integrity": "sha1-C4tILU6bOa8vPXw3WSIpuKzClwU=" + }, "perfect-scrollbar": { "version": "1.5.0", "resolved": "https://registry.npm.taobao.org/perfect-scrollbar/download/perfect-scrollbar-1.5.0.tgz", @@ -12962,6 +12967,14 @@ "@pixi/filter-zoom-blur": "3.1.1" } }, + "pixi-viewport": { + "version": "4.18.1", + "resolved": "https://registry.npm.taobao.org/pixi-viewport/download/pixi-viewport-4.18.1.tgz", + "integrity": "sha1-EP1/72igFjwcKhxvI83KVvzbRvM=", + "requires": { + "penner": "^0.1.3" + } + }, "pixi.js": { "version": "5.3.3", "resolved": "https://registry.npm.taobao.org/pixi.js/download/pixi.js-5.3.3.tgz", diff --git a/package.json b/package.json index ed01b60..d15eb17 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "ngx-perfect-scrollbar": "^8.0.0", "photo-sphere-viewer": "^4.0.7", "pixi-filters": "^3.1.1", + "pixi-viewport": "^4.18.1", "pixi.js": "^5.3.2", "rxjs": "~6.5.4", "swiper": "^5.3.7", diff --git a/src/app/working-area/model/axShape.ts b/src/app/working-area/model/axShape.ts index 06176d7..9409a21 100644 --- a/src/app/working-area/model/axShape.ts +++ b/src/app/working-area/model/axShape.ts @@ -55,8 +55,8 @@ export class AxShape extends Graphics { this.workingArea.selection.all().forEach(item => { const x = event.data.global.x - this.mousePosition.x; const y = event.data.global.y - this.mousePosition.y; - item.x += x * (1 / this.workingArea.backgroundImage.scale.x); - item.y += y * (1 / this.workingArea.backgroundImage.scale.y); + item.x += x * (1 / this.workingArea.camera2D.scale.x); + item.y += y * (1 / this.workingArea.camera2D.scale.y); item.assetData.Point = new PIXI.Point(item.x, item.y); this.workingArea.canvasData.isChange = true; }); diff --git a/src/app/working-area/model/configuration.ts b/src/app/working-area/model/configuration.ts index dc7b517..bf0507a 100644 --- a/src/app/working-area/model/configuration.ts +++ b/src/app/working-area/model/configuration.ts @@ -63,14 +63,21 @@ export const defaultFloorTexture = export const TEXTURE_PROPERTY_COLOR = 'color'; export const TEXTURE_NO_PREVIEW = 'textures/NoPreview.jpg'; -export var config = { dimUnit: dimCentiMeter, wallHeight: 250, - wallThickness: 20, systemUI: false, - scale: 1, snapToGrid: true, - dragOnlyX: false, dragOnlyY: false, - snapTolerance: 50, gridSpacing: 50, - directionalDrag: true, - boundsX: 500, boundsY: 500, - viewBounds: 5000 }; +export var config = { + dimUnit: dimCentiMeter, + wallHeight: 250, + wallThickness: 20, + systemUI: false, + scale: 1, + snapToGrid: true, + dragOnlyX: false, + dragOnlyY: false, + snapTolerance: 50, + gridSpacing: 20, // 50, + directionalDrag: true, + boundsX: 500, + boundsY: 500, + viewBounds: 20000 }; export var wallInformation = { exterior: false, interior: false, midline: true, labels: true, exteriorlabel: 'e:', interiorlabel: 'i:', midlinelabel: 'm:' }; diff --git a/src/app/working-area/model/dimensioning.ts b/src/app/working-area/model/dimensioning.ts index 2ae8000..f7a3fc4 100644 --- a/src/app/working-area/model/dimensioning.ts +++ b/src/app/working-area/model/dimensioning.ts @@ -6,7 +6,7 @@ export const decimals = 1000; export const cmPerFoot = 30.48; export const pixelsPerFoot = 5.0; -export const pixelsPerCm = 0.5; +export const pixelsPerCm = 1; // 0.5; export const cmPerPixel = (1.0 / pixelsPerCm); diff --git a/src/app/working-area/model/grid2D.ts b/src/app/working-area/model/grid2D.ts index b74408d..9683a49 100644 --- a/src/app/working-area/model/grid2D.ts +++ b/src/app/working-area/model/grid2D.ts @@ -33,14 +33,15 @@ export class Grid2D extends Graphics { let spacing = Dimensioning.cmToPixel(spacingCMS); let totalLines = gridSize / spacing; let halfSize = gridSize * 0.5; - let linewidth = Math.max(1.0 / this.gridScale, 1.0); - let highlightLineWidth = Math.max(2.0 / this.gridScale, 1.0); + let linewidth = Math.max(1.0 / this.gridScale, 1.0) * 1/this.canvas.scale.x;// 增加缩放系数 + let highlightLineWidth = Math.max(1 / this.gridScale, 1.0) * 1/this.canvas.scale.x;// 增加缩放系数 let normalColor = 0xE0E0E0; let highlightColor = 0xD0D0D0; + const cellSize = 5; this.clear(); for (let i = 0; i <= totalLines; i++) { let co = (i * spacing) - halfSize; - if (i % 5 === 0) { + if (i % cellSize === 0) { this.lineStyle(highlightLineWidth, highlightColor).moveTo(-halfSize, co).lineTo(halfSize, co); this.lineStyle(highlightLineWidth, highlightColor).moveTo(co, -halfSize).lineTo(co, halfSize); } else { diff --git a/src/app/working-area/working-area.component.html b/src/app/working-area/working-area.component.html index ee66290..736e057 100644 --- a/src/app/working-area/working-area.component.html +++ b/src/app/working-area/working-area.component.html @@ -1,2 +1 @@ -
\ No newline at end of file + \ No newline at end of file diff --git a/src/app/working-area/working-area.component.ts b/src/app/working-area/working-area.component.ts index 263c66b..f806094 100644 --- a/src/app/working-area/working-area.component.ts +++ b/src/app/working-area/working-area.component.ts @@ -19,6 +19,8 @@ import { AxLegend, Legend } from './model/axLegend'; import { AxGrid } from './model/axGrid'; import { AxSelection } from './model/axSelection'; import { AxMessageSystem } from './model/axMessageSystem'; +import { Grid2D } from './model/grid2D'; +import { Viewport } from 'pixi-viewport'; @Component({ @@ -44,7 +46,15 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV /** * pixijs 程序 */ - public app: PIXI.Application; + public app: PIXI.Application = null; + /** + * 相机 + */ + public camera2D: Viewport = null; + /** + * 网格 + */ + public grid2D: Grid2D = null; /** * 资源加载器 */ @@ -137,10 +147,6 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV public animation; public animationIcon; public animationTime; - /** - * 网格 - */ - public grid: AxGrid = null; // 是否按下Ctrl键 isCtrlKeyClicked = false; isMove = false; @@ -258,44 +264,44 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV } /** * - * @param event 鼠标滑动事件 - */ - public mouseWheelHandel(event) { - const delX = this.mousePosition.x - this.backgroundImage.position.x; - const delY = this.mousePosition.y - this.backgroundImage.position.y; - const pivot = this.backgroundImage.toLocal(this.mousePosition); - const delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); - if (delta > 0) { - if (this.backgroundImage.scale.x >= 32) { - this.backgroundImage.scale.x = 32; - this.backgroundImage.scale.y = 32; - this.resizeItem(1 / this.backgroundImage.scale.x); - return; - } - this.backgroundImage.pivot.set(pivot.x, pivot.y); + * @param event 鼠标滑动事件,改用ViewPort控制 + */ + // public mouseWheelHandel(event) { + // const delX = this.mousePosition.x - this.backgroundImage.position.x; + // const delY = this.mousePosition.y - this.backgroundImage.position.y; + // const pivot = this.backgroundImage.toLocal(this.mousePosition); + // const delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail))); + // if (delta > 0) { + // if (this.backgroundImage.scale.x >= 32) { + // this.backgroundImage.scale.x = 32; + // this.backgroundImage.scale.y = 32; + // this.resizeItem(1 / this.backgroundImage.scale.x); + // return; + // } + // this.backgroundImage.pivot.set(pivot.x, pivot.y); - this.backgroundImage.scale.x += this.backgroundImage.scale.x * 0.1; - this.backgroundImage.scale.y += this.backgroundImage.scale.y * 0.1; + // this.backgroundImage.scale.x += this.backgroundImage.scale.x * 0.1; + // this.backgroundImage.scale.y += this.backgroundImage.scale.y * 0.1; - this.backgroundImage.position.x += delX; - this.backgroundImage.position.y += delY; - } else if (delta < 0) { - if (this.backgroundImage.scale.x <= 0.1) { - this.backgroundImage.scale.x = 0.1; - this.backgroundImage.scale.y = 0.1; - this.resizeItem(1 / this.backgroundImage.scale.x); - return; - } - this.backgroundImage.pivot.set(pivot.x, pivot.y); + // this.backgroundImage.position.x += delX; + // this.backgroundImage.position.y += delY; + // } else if (delta < 0) { + // if (this.backgroundImage.scale.x <= 0.1) { + // this.backgroundImage.scale.x = 0.1; + // this.backgroundImage.scale.y = 0.1; + // this.resizeItem(1 / this.backgroundImage.scale.x); + // return; + // } + // this.backgroundImage.pivot.set(pivot.x, pivot.y); - this.backgroundImage.scale.x -= this.backgroundImage.scale.x * 0.1; - this.backgroundImage.scale.y -= this.backgroundImage.scale.y * 0.1; + // this.backgroundImage.scale.x -= this.backgroundImage.scale.x * 0.1; + // this.backgroundImage.scale.y -= this.backgroundImage.scale.y * 0.1; - this.backgroundImage.position.x += delX; - this.backgroundImage.position.y += delY; - } - this.resizeItem(1 / this.backgroundImage.scale.x); - } + // this.backgroundImage.position.x += delX; + // this.backgroundImage.position.y += delY; + // } + // this.resizeItem(1 / this.backgroundImage.scale.x); + // } // 重置图形缩放 public resizeItem(size: number) { this.backgroundImage.children.forEach(item => { @@ -307,27 +313,82 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV } /** * - * @param icon 移动到选中车辆到屏幕中心点 - */ - public moveIconToScreenCenter(icon) { - if (icon.parent === this.backgroundImage && ( - icon.assetData.Type === 1 || - icon.assetData.Type === 2 || - icon.assetData.Type === 3 || - icon.assetData.Type === 4 - )) { - this.backgroundImage.pivot.set(icon.x, icon.y); - this.backgroundImage.position.set(771, 404); - clearTimeout(this.animationTime); - this.animation?.pause(); - this.animationIcon?.scale.set(1); - this.animation = this.animator.breathe(icon, 10, 10, 30, true, 0); - this.animationIcon = icon; - this.animationTime = setTimeout(() => { - this.animation?.pause(); - this.animationIcon?.scale.set(1); - }, 5000); - } + * @param icon 移动到选中车辆到屏幕中心点,改用Viewport控制 + */ + // public moveIconToScreenCenter(icon) { + // if (icon.parent === this.backgroundImage && ( + // icon.assetData.Type === 1 || + // icon.assetData.Type === 2 || + // icon.assetData.Type === 3 || + // icon.assetData.Type === 4 + // )) { + // this.backgroundImage.pivot.set(icon.x, icon.y); + // this.backgroundImage.position.set(771, 404); + // clearTimeout(this.animationTime); + // this.animation?.pause(); + // this.animationIcon?.scale.set(1); + // this.animation = this.animator.breathe(icon, 10, 10, 30, true, 0); + // this.animationIcon = icon; + // this.animationTime = setTimeout(() => { + // this.animation?.pause(); + // this.animationIcon?.scale.set(1); + // }, 5000); + // } + // } + + + /** + * 创建2D相机 + */ + private createViewport(): void { + this.camera2D = new Viewport({ + screenWidth: this.app.view.width, + screenHeight: this.app.view.height, + worldWidth: 20000, + worldHeight: 20000, + interaction: this.app.renderer.plugins.interaction, + }); + + this.app.stage.addChild(this.camera2D); + + this.camera2D + .clamp( + { + left: -10000, + right: 10000, + top: -10000, + bottom: 10000, + }) + .drag() + .pinch() + .wheel() + .clampZoom( + { + minScale: 0.12, + maxScale: 16, + } + ) + .decelerate(); + + this.camera2D.on('wheel', event => { + this.updateCamera2D(); + }); + } + /** + * 更新2D相机 + */ + private updateCamera2D() { + this.grid2D.updateGrid(); + this.resizeItem(1 / this.camera2D.scale.x); + } + + /** + * 创建2D网格 + */ + private createGrid2D(): void { + this.grid2D = new Grid2D(this.camera2D, null); + + this.camera2D.addChild(this.grid2D); } /** * 创建画布 @@ -344,20 +405,11 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.content.nativeElement.appendChild(this.app.view); this.app.view.style.border = '1px dashed blue'; this.animator = new Charm(PIXI); - // 创建网格 - this.grid = new AxGrid(this.app.view.width, null, { color: 0xffffff }, true, true); - // this.grid.x = (this.app.view.width / 2) - (this.grid.gridWidth / 2); - // this.grid.y = (this.app.view.height / 2) - (this.grid.gridWidth / 2); - // this.grid.pivot.set(0.5); - this.grid.x = this.app.stage.x; - this.grid.y = this.app.stage.y; - this.app.stage.addChild(this.grid); - this.grid.drawGrid(); - this.grid.onMousemove = (evt, gridCoord) => { - - }; + this.createViewport(); + this.createGrid2D(); this.createBackgroundImage(); + this.app.ticker.add((delta) => { this.animator.update(); this.mousePosition = this.app.renderer.plugins.interaction.mouse.global; @@ -432,7 +484,27 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.emit('canvasDataChanged'); this.canvasData.isChange = true; }); + // /// + // this.app.renderer.plugins.interaction.on('pointerdown', (event) => { + // if (event.data.button !== 2) { return }; + // this.dragFlag = true; + // this.startPoint = { x: event.data.global.x, y: event.data.global.y }; + // }); + // this.app.renderer.plugins.interaction.on('pointermove', (event) => { + // if (this.dragFlag) { + // const dx = event.data.global.x - this.startPoint.x; + // const dy = event.data.global.y - this.startPoint.y; + // this.app.stage.position.x += dx; + // this.app.stage.position.y += dy; + // this.startPoint = { x: event.data.global.x, y: event.data.global.y }; + // } + // }); + // this.app.renderer.plugins.interaction.on('pointerup', (event) => { + // this.dragFlag = false; + // }); } + // dragFlag; + // startPoint; /** * 重置画布 */ @@ -605,7 +677,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV console.log(this.backgroundImage.toLocal(this.mousePosition)); if (!this.isMove && this.isCtrlKeyClicked === false) { event.currentTarget.data = event.data; - this.isMove = true; + // this.isMove = true; event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent); event.currentTarget.dragPoint.x -= event.currentTarget.x; event.currentTarget.dragPoint.y -= event.currentTarget.y; @@ -801,7 +873,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV } } else if (!this.isMove && this.isCtrlKeyClicked === true) { this.rectToolGraphics.visible = true; - this.isMove = true; + // this.isMove = true; this.initialScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); } @@ -862,7 +934,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.previewImage.visible = false; } }); - this.app.stage.addChild(this.backgroundImage); + this.camera2D.addChild(this.backgroundImage); this.createPreviewImage(); this.createPreviewLineSegment(); this.createCircleShadow(); @@ -893,13 +965,16 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV } this.backgroundImage.scale.set(1); this.backgroundImage.pivot.set(0); - this.backgroundImage.x = this.app.view.width / 2; - this.backgroundImage.y = this.app.view.height / 2; + // this.backgroundImage.x = this.app.view.width / 2; + // this.backgroundImage.y = this.app.view.height / 2; if (imageUrl === undefined || imageUrl === null || imageUrl === '') { this.backgroundImage.texture = this.backgroundTexture; } else { this.backgroundImage.texture = await PIXI.Texture.fromURL(imageUrl); + console.log(imageUrl); } + this.backgroundImage.x = this.backgroundImage.width/2; + this.backgroundImage.y = this.backgroundImage.height/2; this.backgroundImage.angle = imageAngle; // 等待图片加载完成 const imageWidth = this.backgroundImage.texture.width; @@ -908,9 +983,18 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV const appHeight = this.app.view.height; const wScale = appWidth / imageWidth; const hScale = appHeight / imageHeight; - const scale = wScale < hScale ? wScale : hScale; + let scale = wScale < hScale ? wScale : hScale; + + if (scale < 0.12) { + scale = 0.12; + } + if (scale > 16) { + scale = 16; + } + this.camera2D.scale.set(scale); + this.camera2D.x = 235; // 设置图片缩放 - this.backgroundImage.scale.set(scale); + // this.backgroundImage.scale.set(scale); // this.backgroundImage.visible = true; this.backgroundImage.children.forEach((item) => { if (item instanceof AxShape) { @@ -944,6 +1028,8 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV // 创建处置预案图形 this.createNodeShape(this.canvasData.selectPanelPoint.Data); this.createAxLegend(); + + this.updateCamera2D(); } /** * 加载无关联信息处置预案 @@ -965,6 +1051,8 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV }); // 创建处置预案图形 this.createNodeShape(this.canvasData.selectPanelPoint.Data); + + this.updateCamera2D(); } /** * 创建安信图例 @@ -1351,6 +1439,8 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.createNodeShape(this.canvasData.selectPanelPoint.Data); // 隐藏图标 this.setIconVisible(this.canvasData.hiddenBasicInfoFacilities, false); + + this.updateCamera2D(); } /** @@ -1378,6 +1468,8 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.createNodeShape(this.canvasData.selectPanelPoint.Data); // 隐藏图标 this.setIconVisible(this.canvasData.hiddenBasicInfoFacilities, false); + + this.updateCamera2D(); } /** * 考官点击楼层-创建试卷 @@ -1402,6 +1494,8 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV this.createNodeShape(this.canvasData.selectPanelPoint.Data); // 隐藏图标 this.setNameVisible(false, 0); + + this.updateCamera2D(); } //////////////////////////////////////////////////////////////////// 选择逻辑 /**