import { Component, OnInit, ElementRef, ViewChild, AfterViewInit, Input, OnDestroy } from '@angular/core'; import * as PIXI from 'pixi.js'; import { EventEmitter } from 'events'; import { EventManager } from '@angular/platform-browser'; // import { OutlineFilter } from 'pixi-filters'; import { AssetData, CanvasShareDataService, DisposalNodeData, FloorNodeData } from '../canvas-share-data.service'; import * as ObjectID from 'bson-objectid'; import { Charm } from './charm'; import { AxImageShape } from './model/axImageShape'; import { GameMode } from './model/gameMode'; import { MultipointIcon } from './model/multipointIcon'; import { PolygonIcon } from './model/polygonIcon'; import { PaintMode } from './model/paintModel'; import { AxShape } from './model/axShape'; import { PropertyInfo } from './model/PropertyInfo'; import { AxPreviewImageShape } from './model/axPreviewImageShape'; import { AxArrowConnector } from './model/axArrowConnector'; 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'; import { EVENT_SELECTION_CHANGED } from './model/events'; @Component({ selector: 'app-working-area', templateUrl: './working-area.component.html', styleUrls: ['./working-area.component.scss'] }) /** * 工作区 */ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterViewInit, OnDestroy { constructor(private eventManager: EventManager, public canvasData: CanvasShareDataService) { super(); console.log('组件构造函数'); } @ViewChild('content') content: ElementRef; /** * 父组件 */ @Input() init: any; /** * pixijs 程序 */ public app: PIXI.Application = null; /** * 相机 */ public camera2D: Viewport = null; /** * 网格 */ public grid2D: Grid2D = null; /** * 资源加载器 */ public loader = PIXI.Loader.shared; /** * 背景图 */ public backgroundImage: PIXI.Sprite = null; /** * 绘制图片形状时预览状态的图片 */ public previewImage: AxPreviewImageShape = null; /** * 预览线段 */ public previewLineSegment = new PIXI.Graphics(); /** * 预览原点 */ public circleShadow = new PIXI.Graphics(); /** * 鼠标位置 */ public mousePosition: PIXI.Point = new PIXI.Point(0, 0); /** * 绘画模式 */ private paintMode: PaintMode = PaintMode.endPaint; /** * 选择器 */ public selection: AxSelection = new AxSelection(); /** * 当前鼠标的点 */ public currentClickPoint: PIXI.Graphics = new PIXI.Graphics(); /** * 绘制点集合 */ public paintPoints: PIXI.Point[] = []; /** * 绘制中的多点图标 */ public paintingIcon: MultipointIcon; /** * 绘制中的图形 */ public paintingShape: AxShape = null; /** * 绘制中的连线 */ public paintingLine: PIXI.Graphics = new PIXI.Graphics(); /** * 绿色描边 */ // public outlineFilterGreen = new OutlineFilter(2, 0x00ff00); /** * 拷贝素材数据 */ public copyData: any[] = []; /** * 确认绘制按钮 */ private enterPaintEndButton = PIXI.Sprite.from('assets/images/enterPaintButton.png'); /** * 编辑点图片 */ editorPointTexture: PIXI.Texture = PIXI.Texture.from('assets/images/handle-main.png'); backgroundTexture: PIXI.Texture = PIXI.Texture.from('assets/images/noImg.png'); /** * 框选工具图形 */ private rectToolGraphics = new PIXI.Graphics(); /** * 初始鼠标位置 */ private initialScreenMousePos: PIXI.Point = new PIXI.Point(); /** * 最终鼠标位置 */ private finalScreenMousePos: PIXI.Point = new PIXI.Point(); /** * 允许编辑 */ public allowEdit = true; /** * 动画控制器 */ public animator; public animation; public animationIcon; public animationTime; // 是否按下Ctrl键 isCtrlKeyClicked = false; /** * 本软件版本号由四部分组成:<主版本号><次版本号><修订版本号><日期加希腊字母版本号> 例如:1.0.0.20210105_beta * Alpha版: 此版本表示该软件在此阶段主要是以实现软件功能为主,通常只在软件开发者内部交流,一般而言,该版本软件的Bug较多,需要继续修改。 * Beta版: 该版本相对于α版已有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过多次测试来进一步消除,此版本主要的修改对像是软件的UI。 * RC版: 该版本已经相当成熟了,基本上不存在导致错误的BUG,与即将发行的正式版相差无几。 * Release版: 该版本意味“最终版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下,Release不会以单词形式出现在软件封面上,取而代之的是符号®。 */ public VERSION = '1.0.19.20210206_beta'; /** * 数据初始化 */ ngOnInit(): void { console.log('组件OnInit'); PIXI.utils.skipHello(); this.sayHello(); this.eventManager.addGlobalEventListener('window', 'keydown', (event: any) => { }); this.eventManager.addGlobalEventListener('window', 'keyup', (event: any) => { // 按Del键删除选中的图标 if (event.keyCode === 46) { this.deleteSelectedShape(); } }); } ngOnDestroy(): void { console.log('组件OnDestroy'); this.selection.clear(); this.camera2D.destroy(); this.app.destroy(); } public setMulitSelect(b: boolean) { if (b) { this.isCtrlKeyClicked = true; this.camera2D.plugins.pause('drag'); } else { this.isCtrlKeyClicked = false; this.camera2D.drag(); } } /** * 删除选中的图标 */ public deleteSelectedShape() { if (this.selection.size() > 0) { this.selection.all().forEach(axShape => { if (this.allowEdit && this.canvasData.gameMode === axShape.assetData.GameMode) { // 删除图例对象 const temp = this.backgroundImage.getChildByName('图例') as AxLegend; if (temp !== undefined && temp !== null && axShape.assetData.Name !== '图例') { const itemLegend = new Legend(axShape.assetData.Name, axShape.assetData.ImageUrl, 1); temp.deleteItem(itemLegend); } if (axShape.assetData.GameMode === GameMode.BasicInformation) { // 基本信息 // 删除楼层数据 delete this.canvasData.originaleveryStoreyData.data[axShape.assetData.Id]; // 删除建筑数据 delete this.canvasData.originalcompanyBuildingData.data[axShape.assetData.Id]; } else if (axShape.assetData.GameMode === GameMode.Assignment) { // 处置预案 delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[axShape.assetData.Id]; delete this.canvasData.selectPanelPoint.Data.Increment[axShape.assetData.Id]; delete this.canvasData.selectPanelPoint.Data.Stock[axShape.assetData.Id]; } else if (axShape.assetData.GameMode === GameMode.Examinee) { // 考生考试 if (axShape.assetData.Tag === 1) { // 删除楼层数据 delete this.canvasData.examOriginaleveryStoreyData.data[axShape.assetData.Id]; } else { delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[axShape.assetData.Id]; delete this.canvasData.selectPanelPoint.Data.Increment[axShape.assetData.Id]; delete this.canvasData.selectPanelPoint.Data.Stock[axShape.assetData.Id]; } } this.backgroundImage.removeChild(axShape); } }); this.selection.clear(); this.emit('canvasDataChanged'); this.canvasData.isChange = true; AxMessageSystem.send(EVENT_SELECTION_CHANGED); } } /** * 打招呼 */ sayHello() { let _a; if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) { const args = [ '\n %c 版本号 - ' + this.VERSION + '\n', 'color: #ff66a5; background: #000000; padding:5px 0;', ]; (_a = window.console).log.apply(_a, args); } else if (window.console) { window.console.log('\n %c 版本号 - ' + this.VERSION + '\n'); } } /** * 页面初始化 */ ngAfterViewInit(): void { setTimeout(() => { this.createCanvas(); }); window.onresize = () => { this.resetCanvas(); }; } /** * * @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.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.position.x += delX; // this.backgroundImage.position.y += delY; // } // this.resizeItem(1 / this.backgroundImage.scale.x); // } // 重置图形缩放 public resizeItem(size: number) { this.backgroundImage.children.forEach(item => { if (item instanceof AxShape) { item.setItemScale(size); item.drawBorder(size); } }); } /** * * @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.camera2D.pivot.set(0.5); this.camera2D.position = new PIXI.Point(0, 0); 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(); }); this.camera2D.on('pointerdown', event => { if (this.isCtrlKeyClicked === true && event.data.button === 0) { this.rectToolGraphics.visible = true; this.initialScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); } }); this.camera2D.on('pointerup', event => { if (this.isCtrlKeyClicked === true) { this.rectToolGraphics.visible = false; const shapes: AxShape[] = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { // 判断2个矩形是否相交 const rect1 = this.rectToolGraphics.getBounds(); const rect2 = item.getBounds(); if (this.isOverlap(rect1, rect2) && item.interactive) { shapes.push(item); } } }); this.rectToolGraphics.clear(); this.selectAll(shapes); } }); this.camera2D.on('pointerupoutside', event => { if (this.isCtrlKeyClicked === true) { this.rectToolGraphics.visible = false; const shapes: AxShape[] = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { // 判断2个矩形是否相交 const rect1 = this.rectToolGraphics.getBounds(); const rect2 = item.getBounds(); if (this.isOverlap(rect1, rect2) && item.interactive) { shapes.push(item); } } }); this.rectToolGraphics.clear(); this.selectAll(shapes); } }); this.camera2D.on('pointermove', event => { if (this.isCtrlKeyClicked === true && this.rectToolGraphics.visible === true) { this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); const init = this.initialScreenMousePos; const final = this.finalScreenMousePos; this.rectToolGraphics.clear(); this.rectToolGraphics.lineStyle(1 / this.camera2D.scale.x, 0x00ff00, 1); this.rectToolGraphics.beginFill(0xccccf2, 0.25); if (final.x > init.x && final.y > init.y) { this.rectToolGraphics.drawRect(init.x, init.y, final.x - init.x, final.y - init.y); } else if (final.x > init.x && final.y < init.y) { this.rectToolGraphics.drawRect(init.x, final.y, final.x - init.x, init.y - final.y); } else if (final.x < init.x && final.y > init.y) { this.rectToolGraphics.drawRect(final.x, init.y, init.x - final.x, final.y - init.y); } else if (final.x < init.x && final.y < init.y) { this.rectToolGraphics.drawRect(final.x, final.y, init.x - final.x, init.y - final.y); } this.rectToolGraphics.endFill(); } }); // 右键事件 this.camera2D.on('rightclick', event => { event.stopPropagation(); this.deselectAll(); this.setPaintMode(PaintMode.endPaint); }); } /** * 更新2D相机 */ private updateCamera2D() { this.grid2D.updateGrid(); this.resizeItem(1 / this.camera2D.scale.x); } /** * 重置相机 */ public resetCamera2D() { this.camera2D.scale.set(1); this.camera2D.x = (this.app.view.width - this.backgroundImage.width) / 2; this.camera2D.y = (this.app.view.height - this.backgroundImage.height) / 2; this.updateCamera2D(); } /** * 缩放适应 */ public zoomFit() { const imageWidth = this.backgroundImage.texture.width; const imageHeight = this.backgroundImage.texture.height; const appWidth = this.app.view.width - 470; const appHeight = this.app.view.height; const wScale = appWidth / imageWidth; const hScale = appHeight / imageHeight; let scale = wScale < hScale ? wScale : hScale; if (scale < 0.12) { scale = 0.12; } if (scale > 16) { scale = 16; } this.camera2D.scale.set(scale); if (wScale < hScale) { this.camera2D.x = 470 / 2; this.camera2D.y = (appHeight - (imageHeight * this.camera2D.scale.y)) / 2; } else { this.camera2D.x = 470 / 2 + (appWidth - (imageWidth * this.camera2D.scale.x)) / 2; this.camera2D.y = 0; } this.updateCamera2D(); } /** * 创建2D网格 */ private createGrid2D(): void { this.grid2D = new Grid2D(this.camera2D, null); this.camera2D.addChild(this.grid2D); } /** * 创建画布 */ private createCanvas(): void { this.app = new PIXI.Application({ width: this.content.nativeElement.clientWidth, height: this.content.nativeElement.clientHeight, antialias: true, transparent: false, resolution: 1, backgroundColor: 0xE9EAEA }); this.content.nativeElement.appendChild(this.app.view); this.app.view.style.border = '1px dashed blue'; this.animator = new Charm(PIXI); this.createViewport(); this.createGrid2D(); this.createBackgroundImage(); this.app.ticker.add((delta) => { this.animator.update(); this.mousePosition = this.app.renderer.plugins.interaction.mouse.global; // 预览图片 if (this.previewImage !== undefined && this.previewImage !== null) { this.previewImage.position = this.backgroundImage.toLocal(this.mousePosition); } if (this.circleShadow !== undefined && this.circleShadow !== null) { this.circleShadow.position = this.backgroundImage.toLocal(this.mousePosition); this.refreshPreviewLineSegment(this.currentClickPoint.position, this.circleShadow.position); this.refreshPreviewPoint(); } }); /** * 创建图标事件(数据处理) */ this.on('createIcon', (axShape: AxShape) => { if (axShape.assetData.GameMode === GameMode.BasicInformation) { // 基本信息 // 添加楼层数据 this.canvasData.originaleveryStoreyData.data[axShape.assetData.Id] = axShape.assetData; // 添加建筑数据 this.canvasData.originalcompanyBuildingData.data[axShape.assetData.Id] = axShape.assetData; } else if (axShape.assetData.GameMode === GameMode.Assignment) { // 处置预案 if (this.canvasData.selectPanelPoint.Data === undefined || this.canvasData.selectPanelPoint.Data === null) { this.canvasData.selectPanelPoint.Data = new FloorNodeData(); } this.canvasData.selectPanelPoint.Data.Stock[axShape.assetData.Id] = axShape.assetData; } else if (axShape.assetData.GameMode === GameMode.Examinee) { // 考生考试 if (axShape.assetData.Tag === 1) { this.canvasData.examOriginaleveryStoreyData.data[axShape.assetData.Id] = axShape.assetData; } else { if (this.canvasData.selectPanelPoint.Data === undefined || this.canvasData.selectPanelPoint.Data === null) { this.canvasData.selectPanelPoint.Data = new FloorNodeData(); } this.canvasData.selectPanelPoint.Data.Stock[axShape.assetData.Id] = axShape.assetData; } } const temp = this.backgroundImage.getChildByName('图例') as AxLegend; if (temp !== undefined && temp !== null && axShape.assetData.Name !== '图例') { const itemLegend = new Legend(axShape.assetData.Name, axShape.assetData.ImageUrl, 1); temp.addItem(itemLegend); } this.emit('canvasDataChanged'); this.canvasData.isChange = true; this.updateCamera2D(); }); } /** * 重置画布 */ public resetCanvas() { this.app.renderer.resize(this.content.nativeElement.clientWidth, this.content.nativeElement.clientHeight); } /** * 设置名称显示 * @param value true 显示 false 隐藏 * @param mode BasicInformation = 0 基本信息 Assignment想定作业 = 1 想定作业 */ public setNameVisible(value: boolean, mode: GameMode): void { this.backgroundImage?.children.forEach(item => { if (item instanceof AxImageShape) { item.setNameVisible(value, mode); } else if (item instanceof MultipointIcon) { item.setNameVisible(value, mode); } else if (item instanceof PolygonIcon) { item.setNameVisible(value, mode); } else if (item instanceof AxArrowConnector) { item.setNameVisible(value, mode); } }); } /** * 根据id刷新图标 * @param id 图标数据id */ public refreshIcon(id: string): void { const icon = this.backgroundImage.children.find(item => item.name === id); if (icon instanceof AxImageShape) { icon.refresh(); } else if (icon instanceof MultipointIcon) { icon.refresh(); } else if (icon instanceof PolygonIcon) { icon.refresh(); } else if (icon instanceof AxArrowConnector) { icon.redraw(); } else if (icon instanceof AxLegend) { icon.refresh(); } } /** * * @param value 缩放倍数 */ public setIconScale(value: number): void { this.backgroundImage.children.forEach(item => { if (item instanceof AxImageShape) { item.image.scale.set(value); } else if (item instanceof MultipointIcon) { } else if (item instanceof PolygonIcon) { } }); } /** * 创建楼层图形 */ public createFloorShape(floorData: any) { if (floorData === undefined || floorData === null) { return; } Object.keys(floorData).forEach((key) => { switch (floorData[key].InteractiveMode) { case 0: const singleIcon = new AxImageShape(floorData[key], this); singleIcon.allowEdit = this.allowEdit && this.canvasData.gameMode === singleIcon.assetData.GameMode; break; case 1: const icon = new MultipointIcon(floorData[key], this); icon.allowEdit = this.allowEdit && this.canvasData.gameMode === icon.assetData.GameMode; break; case 2: const polygonIcon = new PolygonIcon(floorData[key], this); polygonIcon.allowEdit = this.allowEdit && this.canvasData.gameMode === polygonIcon.assetData.GameMode; break; case 3: if (floorData[key].Name === '水带') { const waterLine = new AxArrowConnector(floorData[key], this, false, true); waterLine.allowEdit = this.allowEdit && this.canvasData.gameMode === waterLine.assetData.GameMode; } else if (floorData[key].Name === '距离') { const distance = new AxArrowConnector(floorData[key], this, true, true); distance.allowEdit = this.allowEdit && this.canvasData.gameMode === distance.assetData.GameMode; } else if (floorData[key].Name === '普通墙' || floorData[key].Name === '承重墙') { const wall = new AxArrowConnector(floorData[key], this, false, false); wall.allowEdit = this.allowEdit && this.canvasData.gameMode === wall.assetData.GameMode; } break; } }); // this.emit('backgroundScale', this.backgroundImage.scale.x); } /** * 创建节点图形 */ public createNodeShape(nodeData: any) { if (nodeData !== undefined && nodeData !== null) { Object.keys(nodeData).forEach((key) => { if (nodeData[key] === undefined || nodeData[key] === null) { return; } Object.keys(nodeData[key]).forEach((tempKey) => { switch (nodeData[key][tempKey].InteractiveMode) { case 0: const singleIcon = new AxImageShape(nodeData[key][tempKey], this); singleIcon.allowEdit = this.allowEdit && this.canvasData.gameMode === singleIcon.assetData.GameMode; break; case 1: const icon = new MultipointIcon(nodeData[key][tempKey], this); icon.allowEdit = this.allowEdit && this.canvasData.gameMode === icon.assetData.GameMode; break; case 2: const polygonIcon = new PolygonIcon(nodeData[key][tempKey], this); polygonIcon.allowEdit = this.allowEdit && this.canvasData.gameMode === polygonIcon.assetData.GameMode; break; case 3: const pipeline = new AxArrowConnector(nodeData[key][tempKey], this, false, true); pipeline.allowEdit = this.allowEdit && this.canvasData.gameMode === pipeline.assetData.GameMode; break; } }); }); } } /** * 创建确认绘制结束按钮 */ private createEnterPaintEndButton() { this.enterPaintEndButton.width = 60; this.enterPaintEndButton.height = 60; this.enterPaintEndButton.anchor.set(0.5); this.enterPaintEndButton.position = new PIXI.Point(0, 0); this.enterPaintEndButton.interactive = true; this.enterPaintEndButton.buttonMode = true; this.enterPaintEndButton .on('pointerdown', event => { event.stopPropagation(); this.enterPaint(); }); this.backgroundImage.addChild(this.enterPaintEndButton); this.enterPaintEndButton.zIndex = this.backgroundImage.children.length; this.enterPaintEndButton.visible = false; } /** * 创建背景图 */ public createBackgroundImage() { this.backgroundImage = PIXI.Sprite.from('assets/images/noImg.png'); this.backgroundImage.anchor.set(0.5); this.backgroundImage.interactive = true; this.backgroundImage.name = 'background'; this.backgroundImage.sortableChildren = true; this.backgroundImage .on('pointerdown', event => { if (event.data.button !== 0) { return; } if (this.isCtrlKeyClicked === false) { switch (this.paintMode) { case PaintMode.endPaint: break; case PaintMode.singlePointIcon: const json = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos)); const list = []; json.forEach(element => { const property = new PropertyInfo(element); list.push(property); }); const assetData = { TemplateId: this.canvasData.selectTemplateData.id, CanConnect: this.canvasData.selectTemplateData.canConnect, Pipelines: new Array(), FloorId: this.canvasData.selectStorey.id, Angle: this.canvasData.selectTemplateData.angle, Color: this.canvasData.selectTemplateData.color, Enabled: this.canvasData.selectTemplateData.enabled, FillMode: this.canvasData.selectTemplateData.fillMode, FireElementId: this.canvasData.selectTemplateData.fireElementId, FixedSize: this.canvasData.selectTemplateData.fixedSize, Height: 32, Width: 32, Id: ObjectID.default.generate(), ImageUrl: this.canvasData.selectTemplateData.imageUrl, InteractiveMode: this.canvasData.selectTemplateData.interactiveMode, MultiPoint: null, Point: new PIXI.Point(this.previewImage.x, this.previewImage.y), Name: this.canvasData.selectTemplateData.name, PropertyInfos: list, Border: this.canvasData.selectTemplateData.border, DrawMode: this.canvasData.selectTemplateData.drawMode, Thickness: this.canvasData.selectTemplateData.thickness, IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding, GameMode: this.canvasData.gameMode, Tag: this.canvasData.selectTemplateData.tag }; const singleIcon = new AxImageShape(assetData, this); this.emit('createIcon', singleIcon); // this.emit('backgroundScale', this.backgroundImage.scale.x); break; case PaintMode.lineIcon: this.previewLineSegment.visible = true; this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y); this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y)); if (this.paintPoints.length >= 2) { this.enterPaintEndButton.position = this.circleShadow.position; this.enterPaintEndButton.visible = true; this.enterPaintEndButton.zIndex = this.backgroundImage.children.length; } if (this.paintingIcon !== null) { this.backgroundImage.removeChild(this.paintingIcon); } const jsonObject = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos)); const propertyList = []; jsonObject.forEach(element => { const property = new PropertyInfo(element); propertyList.push(property); }); const assetData1 = { TemplateId: this.canvasData.selectTemplateData.id, FloorId: this.canvasData.selectStorey.id, Angle: this.canvasData.selectTemplateData.angle, Color: this.canvasData.selectTemplateData.color, Enabled: this.canvasData.selectTemplateData.enabled, FillMode: this.canvasData.selectTemplateData.fillMode, FireElementId: this.canvasData.selectTemplateData.fireElementId, FixedSize: this.canvasData.selectTemplateData.fixedSize, Height: 32, Width: 32, Id: ObjectID.default.generate(), ImageUrl: this.canvasData.selectTemplateData.imageUrl, InteractiveMode: this.canvasData.selectTemplateData.interactiveMode, MultiPoint: JSON.parse(JSON.stringify(this.paintPoints)), Point: new PIXI.Point(0, 0), Name: this.canvasData.selectTemplateData.name, PropertyInfos: propertyList, Border: this.canvasData.selectTemplateData.border, DrawMode: this.canvasData.selectTemplateData.drawMode, Thickness: this.canvasData.selectTemplateData.thickness, IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding, GameMode: this.canvasData.gameMode, Tag: this.canvasData.selectTemplateData.tag }; // const assetData1 = { // ImageUrl: this.canvasData.selectTemplateData.imageUrl, // Point: new PIXI.Point(0, 0), // Width: 32, // Height: 32, // MultiPoint: this.paintPoints, // Name: this.canvasData.selectTemplateData.name // }; this.paintingIcon = new MultipointIcon(assetData1, this); // this.paintingIcon = new MultipointIcon(this.previewSinglePointIcon.texture, new PIXI.Point(0, 0), this.paintPoints, this, // this.canvasData.selectTemplateData.name); // this.emit('backgroundScale', this.backgroundImage.scale.x); break; case PaintMode.polygonIcon: this.previewLineSegment.visible = true; this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y); this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y)); if (this.paintPoints.length === 1) { this.enterPaintEndButton.position = this.circleShadow.position; } else if (this.paintPoints.length >= 3) { this.enterPaintEndButton.visible = true; this.enterPaintEndButton.zIndex = this.backgroundImage.children.length; } this.paintPoints.forEach((value, index, array) => { if (index === 0) { this.paintingLine.clear(); this.paintingLine.lineStyle(1, 0xffd900, 1); this.paintingLine.moveTo(value.x, value.y); } else { this.paintingLine.lineTo(value.x, value.y); } }); // if (this.paintingIcon !== null) { // this.backgroundImage.removeChild(this.paintingIcon); // } // this.paintingIcon = new PolygonIcon(this.paintPoints, this); break; case PaintMode.Pipeline: // if (this.canvasData.selectTemplateData.name === '水带-------') { // if (this.paintingShape !== null) { // this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y); // this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y)); // this.paintingShape.assetData.MultiPoint = JSON.parse(JSON.stringify(this.paintPoints)); // this.paintingShape.refresh(); // } // } else { this.previewLineSegment.visible = true; this.enterPaintEndButton.position = this.circleShadow.position; this.enterPaintEndButton.visible = true; this.enterPaintEndButton.zIndex = this.backgroundImage.children.length; this.currentClickPoint.position = new PIXI.Point(this.circleShadow.x, this.circleShadow.y); this.paintPoints.push(new PIXI.Point(this.circleShadow.x, this.circleShadow.y)); if (this.paintPoints.length < 2) { return; } if (this.paintingShape === null) { const jsonObject = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos)); const propertyList = []; jsonObject.forEach(element => { const property = new PropertyInfo(element); propertyList.push(property); }); const assetData2 = { TemplateId: this.canvasData.selectTemplateData.id, FloorId: this.canvasData.selectStorey.id, Angle: this.canvasData.selectTemplateData.angle, Color: this.canvasData.selectTemplateData.color, Enabled: this.canvasData.selectTemplateData.enabled, FillMode: this.canvasData.selectTemplateData.fillMode, FireElementId: this.canvasData.selectTemplateData.fireElementId, FixedSize: this.canvasData.selectTemplateData.fixedSize, Height: 32, Width: 32, Id: ObjectID.default.generate(), ImageUrl: this.canvasData.selectTemplateData.imageUrl, InteractiveMode: this.canvasData.selectTemplateData.interactiveMode, MultiPoint: JSON.parse(JSON.stringify(this.paintPoints)), Point: new PIXI.Point(0, 0), Name: this.canvasData.selectTemplateData.name, PropertyInfos: propertyList, Border: this.canvasData.selectTemplateData.border, DrawMode: this.canvasData.selectTemplateData.drawMode, Thickness: this.canvasData.selectTemplateData.thickness, IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding, GameMode: this.canvasData.gameMode, Tag: this.canvasData.selectTemplateData.tag }; if (this.canvasData.selectTemplateData.name === '距离') { this.paintingShape = new AxArrowConnector(assetData2, this, true, true); } else if (this.canvasData.selectTemplateData.name === '普通墙' || this.canvasData.selectTemplateData.name === '承重墙') { this.paintingShape = new AxArrowConnector(assetData2, this, false, false); } else if (this.canvasData.selectTemplateData.name === '水带') { this.paintingShape = new AxArrowConnector(assetData2, this, false, true); } } else { this.paintingShape.assetData.MultiPoint = JSON.parse(JSON.stringify(this.paintPoints)); this.paintingShape.redraw(); } // } // this.emit('backgroundScale', this.backgroundImage.scale.x); break; } } // else if (this.isCtrlKeyClicked === true) { // this.rectToolGraphics.visible = true; // this.initialScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); // this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition); // } }) .on('pointerup', event => { }) .on('pointerupoutside', event => { }) .on('pointermove', event => { }) .on('pointerover', (event) => { if (this.previewImage !== null && this.paintMode === PaintMode.singlePointIcon) { this.previewImage.visible = true; } }) .on('pointerout', (event) => { if (this.previewImage !== null && this.paintMode === PaintMode.singlePointIcon) { this.previewImage.visible = false; } }); this.camera2D.addChild(this.backgroundImage); this.createPreviewImage(); this.createPreviewLineSegment(); this.createCircleShadow(); this.createEnterPaintEndButton(); this.backgroundImage.addChild(this.paintingLine); } /** * 判断矩形一是否包含矩形二 * @param rect1 矩形一 * @param rect2 矩形二 */ public isOverlap(rect1, rect2): boolean { const l1 = { x: rect1.x, y: rect1.y }; const r1 = { x: rect1.x + rect1.width, y: rect1.y + rect1.height }; const l2 = { x: rect2.x, y: rect2.y }; const r2 = { x: rect2.x + rect2.width, y: rect2.y + rect2.height }; if ( l1.x > r2.x || l2.x > r1.x || l1.y > r2.y || l2.y > r1.y ) { return false; } return true; } /** * 刷新背景图 */ public async refreshBackgroundImage( imageUrl: string = this.canvasData.selectStorey.imageUrl, imageAngle: number = this.canvasData.selectStorey.imageAngle, imageWidth: number = this.canvasData.selectStorey.imageWidth, imageHeight: number = this.canvasData.selectStorey.imageHeight, ): Promise { if (imageAngle === undefined || imageAngle === null) { imageAngle = 0; } this.backgroundImage.scale.set(1); if (imageUrl === undefined || imageUrl === null || imageUrl === '') { this.backgroundImage.texture = this.backgroundTexture; } else { this.backgroundImage.texture = await PIXI.Texture.fromURL(imageUrl); } this.backgroundImage.x = this.backgroundImage.width / 2; this.backgroundImage.y = this.backgroundImage.height / 2; this.backgroundImage.angle = imageAngle; this.backgroundImage.width = imageWidth; this.backgroundImage.height = imageHeight; this.resetCamera2D(); } /** * 刷新 * @param imageUrl * @param imageAngle */ public async refresh(): Promise { await this.refreshBackgroundImage(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle); // 清空所有图形 this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { itemList.push(item.name); } }); itemList.forEach(item => { this.backgroundImage.getChildByName(item).destroy(); // let child = this.backgroundImage.getChildByName(item); // this.backgroundImage.removeChild(child); }); // 加载当前数据 this.createFloorShape(this.canvasData.originaleveryStoreyData.data); // 创建处置预案图形 this.createNodeShape(this.canvasData.selectPanelPoint.Data); this.createAxLegend(); if (this.canvasData.gameMode == GameMode.Assignment) { this.setLegendVisible(false); } this.updateCamera2D(); } /** * 加载无关联信息处置预案 * @data 处置预案数据 */ public async loadNoRelevantInformationDisposalPlan(data: DisposalNodeData): Promise { await this.refreshBackgroundImage(data.BackgroundImageUrl, data.BackgroundImageAngle); // 清空所有图形 this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { itemList.push(item.name); } }); itemList.forEach(item => { this.backgroundImage.getChildByName(item).destroy(); }); // 创建处置预案图形 this.createNodeShape(this.canvasData.selectPanelPoint.Data); this.updateCamera2D(); } /** * 创建安信图例 */ public createAxLegend() { const tempAssetData = { Id: '图例', Name: '图例', Color: '#066EED80', TemplateId: null, FloorId: this.canvasData.selectStorey.id, Angle: 0, Enabled: null, FillMode: null, FireElementId: null, FixedSize: null, Height: 32, Width: 32, ImageUrl: null, InteractiveMode: null, MultiPoint: null, Point: new PIXI.Point(0, 0), Border: null, DrawMode: null, Thickness: null, IsFromBuilding: null, GameMode: this.canvasData.gameMode, PropertyInfos: [ { Tag: '', Order: 0, Enabled: true, Visible: true, Required: false, RuleName: '', RuleValue: '', PhysicalUnit: '', PropertyName: '列', PropertyType: 2, PropertyValue: 2, }, ], Scale: 1, PivotX: 0, PivotY: 0, }; const shapeMap: Map = new Map(); let data = null; for (const item in this.canvasData.originaleveryStoreyData.data) { if (shapeMap.has(this.canvasData.originaleveryStoreyData.data[item].Name)) { shapeMap.get(this.canvasData.originaleveryStoreyData.data[item].Name).Count++; } else { if (item !== '图例') { shapeMap.set(this.canvasData.originaleveryStoreyData.data[item].Name, new Legend( this.canvasData.originaleveryStoreyData.data[item].Name, this.canvasData.originaleveryStoreyData.data[item].ImageUrl, 1 )); } else { data = this.canvasData.originaleveryStoreyData.data[item]; } } } if (data === null) { const axLegend = new AxLegend(tempAssetData, this, shapeMap); const rect = this.backgroundImage.getLocalBounds(); const itemRect = axLegend.getLocalBounds(); axLegend.x = rect.right - itemRect.right; axLegend.y = rect.bottom - itemRect.bottom; axLegend.assetData.Point = new PIXI.Point(axLegend.x, axLegend.y); this.emit('createIcon', axLegend); } else { const axLegend = new AxLegend(data, this, shapeMap); } } // /** // * 清空画布 // */ // public destroyBackgroundImage(): void { // this.app.stage.removeChild(this.backgroundImage); // this.backgroundImage = null; // } /** // // * 设置背景图缩放 // // * @param scale 缩放系数 // // */ // public setBackgroundScale(scale: number): void { // this.backgroundImage?.scale.set(scale); // this.emit('backgroundScale', this.backgroundImage?.scale.x); // } // /** // * 设置背景图角度 // * @param imageAngle 角度值 // */ // public setBackgroundAngle(imageAngle: number) { // this.backgroundImage.angle = imageAngle; // } /** * 创建预览单点图标 */ private createPreviewImage(): void { this.previewImage = new AxPreviewImageShape(this); this.previewImage.visible = false; } /** * 创建预览线段 */ private createPreviewLineSegment() { this.previewLineSegment.visible = false; this.backgroundImage.addChild(this.currentClickPoint); this.backgroundImage.addChild(this.previewLineSegment); this.backgroundImage.addChild(this.rectToolGraphics); this.rectToolGraphics.visible = false; } /** * 刷新预览线段 * @param pointA 点A * @param pointB 点B */ private refreshPreviewLineSegment(pointA: PIXI.Point, pointB: PIXI.Point) { this.previewLineSegment.clear(); this.previewLineSegment.lineStyle(1 / this.backgroundImage.scale.x, 0x00ff00, 1); this.previewLineSegment.moveTo(pointA.x, pointA.y); this.previewLineSegment.lineTo(pointB.x, pointB.y); } /** * 创建半径图标影子 * @param x 半径 */ private createCircleShadow(): void { this.circleShadow.visible = false; this.backgroundImage.addChild(this.circleShadow); } /** * 刷新预览点 */ private refreshPreviewPoint() { this.circleShadow.clear(); this.circleShadow.beginFill(0x00ff00); this.circleShadow.drawCircle(0, 0, 5 / this.backgroundImage.scale.x); this.circleShadow.endFill(); } /** * 开始绘制 */ public beginPaint() { this.deselectAll(); this.setPaintMode(PaintMode.endPaint); this.setPaintMode(this.canvasData.selectTemplateData.interactiveMode); } /** * 初始化管线数据 */ public initPipelineData(): void { this.paintPoints = []; this.paintingShape = null; } public beginPaintingArrows(): void { this.paintMode = PaintMode.Arrows; } /** * 设置绘制状态 * @param mode 状态 */ public setPaintMode(mode: PaintMode) { if (this.paintMode === mode) { return; } this.paintMode = mode; switch (this.paintMode) { case PaintMode.singlePointIcon: this.previewImage.visible = true; this.previewImage.setImageUrl(this.canvasData.selectTemplateData.imageUrl); break; case PaintMode.lineIcon: this.circleShadow.visible = false; this.previewLineSegment.visible = false; this.paintPoints.splice(0, this.paintPoints.length); if (this.paintingIcon !== null) { this.backgroundImage.removeChild(this.paintingIcon); } this.previewImage.setImageUrl(this.canvasData.selectTemplateData.imageUrl); this.circleShadow.visible = true; break; case PaintMode.polygonIcon: this.circleShadow.visible = false; this.previewLineSegment.visible = false; this.paintingIcon = null; this.paintPoints.splice(0, this.paintPoints.length); this.paintingLine.clear(); this.circleShadow.visible = true; break; case PaintMode.Pipeline: break; case PaintMode.endPaint: if (this.previewImage !== null) { this.previewImage.visible = false; } // 重置组件状态 if (this.paintingIcon !== undefined && this.paintingIcon !== null) { this.backgroundImage.removeChild(this.paintingIcon); } if (this.paintingShape !== null) { this.backgroundImage.removeChild(this.paintingShape); this.paintingShape = null; } this.enterPaintEndButton.visible = false; this.paintingLine.clear(); this.resetData(); break; default: break; } } /** * 获取绘制状态 */ public getPaintMode(): PaintMode { return this.paintMode; } /** * 重置 */ public resetData() { this.initPipelineData(); // this.circleShadow.visible = false; this.previewLineSegment.visible = false; } /** * 确认绘制 */ private enterPaint(): void { this.previewLineSegment.visible = false; this.enterPaintEndButton.visible = false; switch (this.paintMode) { case PaintMode.singlePointIcon: break; case PaintMode.lineIcon: if (this.paintPoints.length >= 2) { this.emit('createIcon', this.paintingIcon); this.paintingIcon = null; } break; case PaintMode.polygonIcon: this.paintingLine.clear(); if (this.paintPoints.length >= 3) { const jsonList = JSON.parse(JSON.stringify(this.canvasData.selectTemplateData.propertyInfos)); const propertyList = []; jsonList.forEach(element => { const property = new PropertyInfo(element); propertyList.push(property); }); const assetData = { TemplateId: this.canvasData.selectTemplateData.id, FloorId: this.canvasData.selectStorey.id, Angle: this.canvasData.selectTemplateData.angle, Color: this.canvasData.selectTemplateData.color, Enabled: this.canvasData.selectTemplateData.enabled, FillMode: this.canvasData.selectTemplateData.fillMode, FireElementId: this.canvasData.selectTemplateData.fireElementId, FixedSize: this.canvasData.selectTemplateData.fixedSize, Height: 32, Width: 32, Id: ObjectID.default.generate(), ImageUrl: this.canvasData.selectTemplateData.imageUrl, InteractiveMode: this.canvasData.selectTemplateData.interactiveMode, MultiPoint: JSON.parse(JSON.stringify(this.paintPoints)), Point: new PIXI.Point(0, 0), Name: this.canvasData.selectTemplateData.name, PropertyInfos: propertyList, Border: this.canvasData.selectTemplateData.border, DrawMode: this.canvasData.selectTemplateData.drawMode, Thickness: this.canvasData.selectTemplateData.thickness, IsFromBuilding: this.canvasData.selectTemplateData.isFromBuilding, GameMode: this.canvasData.gameMode }; const polygonIcon = new PolygonIcon(assetData, this); this.emit('createIcon', polygonIcon); } break; case PaintMode.Pipeline: this.emit('createIcon', this.paintingShape); this.paintingShape = null; break; } this.paintPoints.splice(0, this.paintPoints.length); } /** * 复制 */ public copy(): void { this.copyData = []; this.selection.all().forEach(item => { const newData = JSON.parse(JSON.stringify(item.assetData)); this.copyData.push(newData); }); } /** * 粘贴 */ public paste(companyId: string, buildingId: string, floorId: string): void { const ids: string[] = []; if (this.copyData.length > 0) { this.copyData.forEach(item => { item.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5); const newData = JSON.parse(JSON.stringify(item)); newData.Id = ObjectID.default.generate(), newData.CompanyId = companyId; newData.BuildingId = buildingId; newData.FloorId = floorId; newData.Point = new PIXI.Point(item.Point.x + 5, item.Point.y + 5); switch (item.InteractiveMode) { case PaintMode.singlePointIcon: const singleIcon = new AxImageShape(newData, this); this.emit('createIcon', singleIcon); break; case PaintMode.lineIcon: const lineIcon = new MultipointIcon(newData, this); this.emit('createIcon', lineIcon); break; case PaintMode.polygonIcon: const polygonIcon = new PolygonIcon(newData, this); this.emit('createIcon', polygonIcon); break; case PaintMode.Pipeline: if (item.Name === '距离') { const wall = new AxArrowConnector(newData, this, true, true); this.emit('createIcon', wall); } else if (item.Name === '普通墙' || item.Name === '承重墙') { const wall = new AxArrowConnector(newData, this, false, false); this.emit('createIcon', wall); } break; } ids.push(newData.Id); }); this.setHighlight(ids); } } //////////////////////////////////////////////////////////////////////// 通用///////////////////////////////////////////////////////////////////////////// /** * * @param id 图标ID * @param b 显示/隐藏 */ public setIconVisible(ids: string[], b: boolean) { ids.forEach(item => { this.backgroundImage.getChildByName(item).visible = b; }); } //////////////////////////////////////////////////////////////////////// 采集平台加载逻辑/////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// 编制平台加载逻辑/////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// 考试系统加载逻辑/////////////////////////////////////////////////////////////////////// /** * 考生点击楼层 */ public async onExamineeClickFloor() { await this.refreshBackgroundImage(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle); // 清空所有图形 this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { itemList.push(item.name); } }); itemList.forEach(item => { this.backgroundImage.getChildByName(item).destroy(); }); // 创建楼层图形 this.createFloorShape(this.canvasData.examOriginaleveryStoreyData.data); // 创建楼层图形 this.createFloorShape(this.canvasData.originaleveryStoreyData.data); // 创建处置预案图形 this.createNodeShape(this.canvasData.selectPanelPoint.Data); // 隐藏图标 this.setIconVisible(this.canvasData.hiddenBasicInfoFacilities, false); this.updateCamera2D(); } /** * 考官点击楼层-阅卷 */ public async onExaminerClickFloor() { await this.refreshBackgroundImage(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle); // 清空所有图形 this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { itemList.push(item.name); } }); itemList.forEach(item => { this.backgroundImage.getChildByName(item).destroy(); }); // 创建楼层图形 this.createFloorShape(this.canvasData.examOriginaleveryStoreyData.data); // 创建楼层图形 this.createFloorShape(this.canvasData.originaleveryStoreyData.data); // 创建处置预案图形 this.createNodeShape(this.canvasData.selectPanelPoint.Data); // 隐藏图标 this.setIconVisible(this.canvasData.hiddenBasicInfoFacilities, false); this.updateCamera2D(); } /** * 考官点击楼层-创建试卷 */ public async onExaminerClickFloor_CreateTestpaper() { await this.refreshBackgroundImage(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle); // 清空所有图形 this.deselectAll(); const itemList = []; this.backgroundImage.children.forEach(item => { if (item instanceof AxShape && item instanceof AxPreviewImageShape === false) { itemList.push(item.name); } }); itemList.forEach(item => { this.backgroundImage.getChildByName(item).destroy(); }); // 创建楼层图形 this.createFloorShape(this.canvasData.originaleveryStoreyData.data); // 创建处置预案图形 this.createNodeShape(this.canvasData.selectPanelPoint.Data); // 隐藏图标 this.setNameVisible(false, 0); this.updateCamera2D(); } //////////////////////////////////////////////////////////////////// 选择逻辑 /** * 清空选择,选择单个形状 * @param shape 形状 */ public selectSingle(shape: AxShape) { if (this.selection.first() !== null) { this.selection.all().forEach(item => { this.clearSelectEffect(item); }); this.selection.clear(); } this.selection.add(shape); this.setSelectEffect(shape); AxMessageSystem.send(EVENT_SELECTION_CHANGED); } /** * 选择 * @param shape 形状 */ public select(shape: AxShape) { if (this.selection.first() !== null && !this.isCtrlKeyClicked && !this.selection.has(shape)) { this.selection.all().forEach(item => { this.clearSelectEffect(item); }); this.selection.clear(); } this.selection.add(shape); this.setSelectEffect(shape); AxMessageSystem.send(EVENT_SELECTION_CHANGED); } /** * 选择集合中的形状 * @param shape 形状集合 */ public selectAll(shape: AxShape[]) { if (shape.length > 0) { this.selection.addArray(shape); this.selection.all().forEach(item => { this.setSelectEffect(item); }); AxMessageSystem.send(EVENT_SELECTION_CHANGED); } } /** * 先清空再选择全部 * @param shape 形状集合 */ public selectAllWithClear(shape: AxShape[]) { if (this.selection.first() !== null) { this.selection.all().forEach(item => { this.clearSelectEffect(item); }); this.selection.clear(); } this.selection.addArray(shape); this.selection.all().forEach(item => { this.setSelectEffect(item); }); AxMessageSystem.send(EVENT_SELECTION_CHANGED); } /** * 选择集合中所有id的形状 * @param ids 形状id集合 */ public setHighlight(ids: string[]): void { const shapes: AxShape[] = []; // 重新选择 ids.forEach(item => { const obj = this.backgroundImage.getChildByName(item); shapes.push(obj as AxShape); }); this.selectAllWithClear(shapes); } /** * 取消所有选择 */ public deselectAll() { if (this.selection.first() !== null) { this.selection.all().forEach(item => { this.clearSelectEffect(item); }); this.selection.clear(); AxMessageSystem.send(EVENT_SELECTION_CHANGED); } } /** * 设置选中效果 * @param shape 形状 */ public setSelectEffect(shape: AxShape) { shape.hideBorder(); shape.setPointVisiable(false); shape.showBorder(); shape.drawBorder(1 / this.backgroundImage.scale.x); shape.setPointVisiable(this.allowEdit); } /** * 设置形状选中效果 * @param shape 形状 */ public clearSelectEffect(shape: AxShape) { shape.hideBorder(); shape.setPointVisiable(false); } //////////////////////////////////////////////////////////////////////////////////////////////// 图例 /** * 设置图例显示隐藏 * @param b true 显示,false隐藏 */ public setLegendVisible(b: boolean): void { const legend = this.backgroundImage.getChildByName('图例') as AxLegend; legend.interactive = b; legend.visible = b; } }