考核考试系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1338 lines
49 KiB

import { Component, OnInit, ElementRef, ViewChild, AfterViewInit, Input } 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';
@Component({
selector: 'app-working-area',
templateUrl: './working-area.component.html',
styleUrls: ['./working-area.component.scss']
})
/**
* 工作区
*/
export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterViewInit {
constructor(private eventManager: EventManager, public canvasData: CanvasShareDataService) {
super();
}
@ViewChild('content')
content: ElementRef;
/**
* 父组件
*/
@Input() init: any;
/**
* pixijs 程序
*/
public app: PIXI.Application;
/**
* 资源加载器
*/
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: Selection = new Selection(this);
/**
* 当前鼠标的点
*/
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');
/**
* 框选工具图形
*/
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;
// 车辆作业面
public carAreas: PolygonIcon[];
// 车辆数据
public carData: Map<string, any> = new Map<string, any>();
// 当前选择的车辆id
public selectCar: any = null;
/**
* 数据初始化
*/
ngOnInit(): void {
this.eventManager.addGlobalEventListener('window', 'keydown', (event: any) => {
if (event.keyCode === 17) {
this.selection.isMultiselection = true;
}
});
this.eventManager.addGlobalEventListener('window', 'keyup', (event: any) => {
if (event.keyCode === 17) {
this.selection.isMultiselection = false;
this.rectToolGraphics.visible = false;
this.rectToolGraphics.clear();
}
// 按Del键删除选中的图标
if (event.keyCode === 46) {
this.selection.objects.forEach(item => {
if (this.allowEdit
&& this.canvasData.gameMode === item.assetData.GameMode) {
this.backgroundImage.removeChild(this.backgroundImage.getChildByName(item.assetData.Id));
}
});
this.selection.deselectAll();
this.emit('deleteIcon');
}
});
}
/**
* 页面初始化
*/
ngAfterViewInit(): void {
this.createCanvas();
window.onresize = () => {
this.resetCanvas();
};
}
/**
*
* @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.emit('backgroundScale', 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.emit('backgroundScale', 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.emit('backgroundScale', this.backgroundImage.scale.x);
}
/**
*
* @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
)) {
console.log(this.backgroundImage.position);
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);
}
}
/**
* 创建画布
*/
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: 0xE9FAFF
});
this.content.nativeElement.appendChild(this.app.view);
this.animator = new Charm(PIXI);
this.app.ticker.add((delta) => {
this.animator.update();
this.mousePosition = this.app.renderer.plugins.interaction.mouse.global;
// 预览图片
if (this.previewImage !== null && this.backgroundImage !== null) {
this.previewImage.position = this.backgroundImage.toLocal(this.mousePosition);
}
if (this.circleShadow !== null && this.backgroundImage !== null) {
this.circleShadow.position = this.backgroundImage.toLocal(this.mousePosition);
this.refreshPreviewLineSegment(this.currentClickPoint.position, this.circleShadow.position);
this.refreshPreviewPoint();
}
/**
* 显示框选
*/
if (this.rectToolGraphics.visible === true) {
const init = this.initialScreenMousePos;
const final = this.finalScreenMousePos;
this.rectToolGraphics.clear();
this.rectToolGraphics.lineStyle(2, 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.on('select', shape => {
if (shape instanceof AxShape) {
shape.showBorder();
shape.setPointVisiable(this.allowEdit);
}
});
/**
* 取消选中事件
*/
this.on('deselect', shape => {
if (shape instanceof AxShape) {
shape.hideBorder();
shape.setPointVisiable(false);
}
});
/**
* 根据背景缩放事件
*/
this.on('backgroundScale', scale => {
const data = 1 / scale;
this.backgroundImage?.children.forEach(item => {
if (item instanceof AxImageShape) {
item.setItemScale(data);
item.drawBorder(data);
} else if (item instanceof MultipointIcon) {
item.setItemScale(data);
item.drawBorder(data);
} else if (item instanceof PolygonIcon) {
item.setItemScale(data);
item.drawBorder(data);
} else if (item instanceof AxPreviewImageShape) {
item.scale.set(data);
} else if (item instanceof AxArrowConnector) {
item.setItemScale(data);
item.drawBorder(data);
}
});
});
/**
* 创建图标事件(数据处理)
*/
this.on('createIcon', obj => {
if (obj.assetData.GameMode === GameMode.BasicInformation) { // 基本信息
// 添加楼层数据
this.canvasData.originaleveryStoreyData.data[obj.assetData.Id] = obj.assetData;
// 添加建筑数据
this.canvasData.originalcompanyBuildingData.data[obj.assetData.Id] = obj.assetData;
} else if (obj.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[obj.assetData.Id] = obj.assetData;
} else if (obj.assetData.GameMode === GameMode.Examinee) { // 考生考试
if (obj.assetData.Tag === 1) {
this.canvasData.examOriginaleveryStoreyData.data[obj.assetData.Id] = obj.assetData;
} else {
if (this.canvasData.selectPanelPoint.Data === undefined
|| this.canvasData.selectPanelPoint.Data === null) {
this.canvasData.selectPanelPoint.Data = new FloorNodeData();
}
this.canvasData.selectPanelPoint.Data.Stock[obj.assetData.Id] = obj.assetData;
}
}
this.canvasData.isChange = true;
});
/**
* 删除图标事件(数据处理)
*/
this.on('deleteIcon', obj => {
if (obj.assetData.GameMode === GameMode.BasicInformation) { // 基本信息
// 删除楼层数据
delete this.canvasData.originaleveryStoreyData.data[obj.assetData.Id];
// 删除建筑数据
delete this.canvasData.originalcompanyBuildingData.data[obj.assetData.Id];
} else if (obj.assetData.GameMode === GameMode.Assignment) { // 处置预案
delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[obj.assetData.Id];
delete this.canvasData.selectPanelPoint.Data.Increment[obj.assetData.Id];
delete this.canvasData.selectPanelPoint.Data.Stock[obj.assetData.Id];
} else if (obj.assetData.GameMode === GameMode.Examinee) { // 考生考试
if (obj.assetData.Tag === 1) {
// 删除楼层数据
delete this.canvasData.examOriginaleveryStoreyData.data[obj.assetData.Id];
} else {
delete this.canvasData.selectPanelPoint.Data.DefinedIncrement[obj.assetData.Id];
delete this.canvasData.selectPanelPoint.Data.Increment[obj.assetData.Id];
delete this.canvasData.selectPanelPoint.Data.Stock[obj.assetData.Id];
}
this.canvasData.isChange = true;
}
});
}
/**
* 重置画布
*/
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);
}
});
}
/**
* 根据id刷新图标
* @param id 图标数据id
*/
public refreshIcon(id: string): void {
const icon = this.backgroundImage.children.find(item => item.name === id);
console.log(icon);
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();
}
}
/**
*
* @param value 缩放倍数
*/
public setIconScale(value: number): void {
this.backgroundImage.children.forEach(item => {
if (item instanceof AxImageShape) {
console.log(item.image.scale);
item.image.scale.set(value);
} else if (item instanceof MultipointIcon) {
} else if (item instanceof PolygonIcon) {
}
});
}
/**
* 设置高亮
*/
public setHighlight(ids: string[]): void {
this.selection.deselectAll();
ids.forEach(item => {
let obj = this.backgroundImage.getChildByName(item);
if (obj === null) {
obj = this.app.stage.getChildByName(item);
}
this.selection.select(obj);
});
}
/**
* 创建背景图
*/
public createBackground(imageUrl:string,imageAngle:number) {
if (this.backgroundImage !== null) {
this.backgroundImage.destroy();
this.backgroundImage = null;
}
this.createBackgroundImage()
this.refreshBackgroundImage(imageUrl,imageAngle);
}
/**
* 创建楼层图形
*/
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.moveable = this.allowEdit && this.canvasData.gameMode === singleIcon.assetData.GameMode;
break;
case 1:
const icon = new MultipointIcon(floorData[key], this);
break;
case 2:
const polygonIcon = new PolygonIcon(floorData[key], this);
break;
case 3:
if (floorData[key].Name === '水带') {
const distance = new AxArrowConnector(floorData[key], this, false, true);
} else if(floorData[key].Name === '距离'){
const distance = new AxArrowConnector(floorData[key], this, true, true);
}else if(floorData[key].Name === '普通墙' || floorData[key].Name === '承重墙'){
const wall = new AxArrowConnector(floorData[key], this, false, false);
}
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.moveable = this.allowEdit && this.canvasData.gameMode === singleIcon.assetData.GameMode;
break;
case 1:
const icon = new MultipointIcon(nodeData[key][tempKey], this);
break;
case 2:
const polygonIcon = new PolygonIcon(nodeData[key][tempKey], this);
break;
case 3:
const pipeline = new AxArrowConnector(nodeData[key][tempKey], this,false,true);
break;
}
});
});
}
this.emit('backgroundScale', this.backgroundImage.scale.x);
}
/**
* 创建确认绘制结束按钮
*/
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('mousedown', 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.x = this.app.view.width / 2;
this.backgroundImage.y = this.app.view.height / 2;
this.backgroundImage.interactive = true;
this.backgroundImage.name = 'background';
this.backgroundImage.angle = this.canvasData.selectStorey.imageAngle;
const imageWidth = 665;
const imageHeight = 530;
const appWidth = this.app.view.width - 470;
const appHeight = this.app.view.height;
const wScale = appWidth / imageWidth;
const hScale = appHeight / imageHeight;
const scale = wScale < hScale
? wScale
: hScale;
this.backgroundImage.scale.set(scale);
this.backgroundImage.sortableChildren = true;
this.backgroundImage
.on('mousedown', event => {
if (!event.currentTarget.dragging && this.selection.isMultiselection === false) {
this.selection.deselectAll();
event.currentTarget.data = event.data;
event.currentTarget.dragging = true;
event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent);
event.currentTarget.dragPoint.x -= event.currentTarget.x;
event.currentTarget.dragPoint.y -= event.currentTarget.y;
switch (this.paintMode) {
case PaintMode.endPaint:
console.log(this.backgroundImage.toLocal(this.mousePosition));
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;
}
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.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.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 {
this.paintingShape.assetData.MultiPoint = JSON.parse(JSON.stringify(this.paintPoints));
this.paintingShape.redraw();
}
}
this.emit('backgroundScale', this.backgroundImage.scale.x);
break;
}
} else if (!event.currentTarget.dragging && this.selection.isMultiselection === true) {
this.rectToolGraphics.visible = true;
event.currentTarget.dragging = true;
this.initialScreenMousePos = this.backgroundImage.toLocal(this.mousePosition);
this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition);
}
})
.on('mouseup', event => {
if (event.currentTarget.dragging) {
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
if (this.rectToolGraphics.visible === true) {
this.backgroundImage.children.forEach(item => {
if ( item instanceof AxImageShape
|| item instanceof MultipointIcon
|| item instanceof PolygonIcon
|| item instanceof AxArrowConnector) {
// 判断2个矩形是否相交
const rect1 = this.rectToolGraphics.getBounds();
const rect2 = item.getBounds();
if (this.isOverlap(rect1, rect2)) {
this.selection.select(item);
}
}
});
this.rectToolGraphics.clear();
this.rectToolGraphics.visible = false;
}
})
.on('mouseupoutside', event => {
if (event.currentTarget.dragging) {
event.currentTarget.dragging = false;
event.currentTarget.data = null;
}
})
.on('mousemove', event => {
if (event.currentTarget.dragging && this.selection.isMultiselection === false) {
const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
event.currentTarget.x = newPosition.x - event.currentTarget.dragPoint.x;
event.currentTarget.y = newPosition.y - event.currentTarget.dragPoint.y;
} else if (event.currentTarget.dragging && this.selection.isMultiselection === true) {
if (this.rectToolGraphics.visible === true) {
this.finalScreenMousePos = this.backgroundImage.toLocal(this.mousePosition);
}
}
})
.on('rightclick', event => {
event.stopPropagation();
this.selection.deselectAll();
this.setPaintMode(PaintMode.endPaint);
})
.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.app.stage.addChild(this.backgroundImage);
this.createPreviewImage();
this.createPreviewLineSegment();
this.createCircleShadow();
this.createEnterPaintEndButton();
this.backgroundImage.addChild(this.paintingLine);
}
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): Promise<void> {
if (!imageUrl) {
this.backgroundImage.visible = false;
} else {
this.backgroundImage.texture = await PIXI.Texture.fromURL(imageUrl);
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;
const scale = wScale < hScale? wScale: hScale;
this.backgroundImage.scale.set(scale);
this.backgroundImage.angle = imageAngle;
this.backgroundImage.visible = true;
}
}
/**
* 清空画布
*/
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 {
// if (this.previewSinglePointIcon === null) {
// this.previewSinglePointIcon = PIXI.Sprite.from(this.canvasData.selectTemplateData.imageUrl);
// this.previewSinglePointIcon.width = this.canvasData.selectTemplateData.width;
// this.previewSinglePointIcon.height = this.canvasData.selectTemplateData.height;
// this.previewSinglePointIcon.anchor.set(0.5);
// this.previewSinglePointIcon.interactive = false;
// this.backgroundImage.addChild(this.previewSinglePointIcon);
// this.previewSinglePointIcon.scale.set(1 / this.backgroundImage.scale.x);
// }
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.beginFill(0xFFCC5A);
// this.circleShadow.drawCircle(0, 0, 10);
// this.circleShadow.endFill();
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();
}
showConnectionPoint(b: boolean) {
this.backgroundImage?.children.forEach(item => {
if (item instanceof AxImageShape) {
if (item.assetData.CanConnect) {
item.showConnectionPoint(b);
}
}
});
}
/**
* 开始绘制
*/
public beginPaint() {
console.log(this.canvasData.selectTemplateData);
this.selection.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:
if (this.canvasData.selectTemplateData.name==='水带') {
this.showConnectionPoint(true);
} else {
}
break;
case PaintMode.endPaint:
this.showConnectionPoint(false);
if (this.previewImage !== null) {
this.previewImage.visible = false;
}
// 重置组件状态
if ( this.paintingIcon !== undefined
&& this.paintingIcon !== null) {
this.backgroundImage.removeChild(this.paintingIcon);
}
// if (this.paintingShape !== undefined
// && this.paintingShape !== null) {
// this.backgroundImage.removeChild(this.paintingShape);
// }
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;
console.log(this.paintMode);
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:
if (this.canvasData.selectTemplateData.name !== '水带') {
this.emit('createIcon', this.paintingShape);
this.paintingShape = null;
}
break;
}
this.paintPoints.splice(0, this.paintPoints.length);
this.emit('backgroundScale', this.backgroundImage.scale.x);
}
/**
* 复制
*/
public copy(): void {
this.copyData = [];
this.selection.objects.forEach(item => {
const newData = JSON.parse(JSON.stringify(item.assetData));
this.copyData.push(newData);
});
}
/**
* 粘贴
*/
public paste(companyId: string, buildingId: string, floorId: string): void {
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);
// if (newData.IsFromBuilding) {
// this.canvasData.originalcompanyBuildingData.data[newData.Id] = newData;
// } else {
this.canvasData.originaleveryStoreyData.data[newData.Id] = newData;
// }
switch (item.InteractiveMode) {
case PaintMode.singlePointIcon:
const singleIcon = new AxImageShape(newData, this);
break;
case PaintMode.lineIcon:
const lineIcon = new MultipointIcon(newData, this);
break;
case PaintMode.polygonIcon:
const polygonIcon = new PolygonIcon(newData, this);
break;
case PaintMode.Pipeline:
if (item.Name === '距离') {
const wall = new AxArrowConnector(newData, this,true,true);
} else if (item.Name === '普通墙' || item.Name === '承重墙') {
const wall = new AxArrowConnector(newData, this,false,false);
}
break;
}
this.selection.select(this.backgroundImage.getChildByName(newData.Id));
});
this.emit('backgroundScale', this.backgroundImage.scale.x);
}
////////////////////////////////////////////////////////////////////////通用/////////////////////////////////////////////////////////////////////////////
/**
*
* @param id 图标ID
* @param b 显示/隐藏
*/
public setIconVisible(ids: string[], b: boolean) {
ids.forEach(item => {
this.backgroundImage.getChildByName(item).visible = b;
});
}
////////////////////////////////////////////////////////////////////////采集平台加载逻辑///////////////////////////////////////////////////////////////////////
public onBasicInformationClickFloor() {
}
////////////////////////////////////////////////////////////////////////编制平台加载逻辑///////////////////////////////////////////////////////////////////////
public onClickAssignmentFloor() {
}
////////////////////////////////////////////////////////////////////////考试系统加载逻辑///////////////////////////////////////////////////////////////////////
/**
* 处理考生隐藏数据
*/
public processinghiddenData() {
for (let key in this.canvasData.originaleveryStoreyData.data){
if (this.canvasData.hiddenBasicInfoFacilities.indexOf(key)!==-1) {
delete this.canvasData.originaleveryStoreyData.data[key];
}
}
}
/**
* 考生点击楼层
*/
public onExamineeClickFloor() {
// // 创建背景图
// this.createBackground(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle);
// // 创建楼层图形
// this.createFloorShape(this.canvasData.examOriginaleveryStoreyData.data);
// // 处理共享数据中考官隐藏的数据
// this.processinghiddenData();
// // 建楼层图形
// this.createFloorShape(this.canvasData.originaleveryStoreyData.data);
// // 创建处置预案图形
// this.createNodeShape(this.canvasData.selectPanelPoint.Data);
// // 隐藏基本信息图形
// this.setNameVisible(false, 0);
// // 隐藏想定作业图形
// this.setNameVisible(false, 1);
// console.log("考生加载................................")
// 创建背景图
this.createBackground(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle);
// 创建楼层图形
this.createFloorShape(this.canvasData.examOriginaleveryStoreyData.data);
// 创建楼层图形
this.createFloorShape(this.canvasData.originaleveryStoreyData.data);
// 创建处置预案图形
this.createNodeShape(this.canvasData.selectPanelPoint.Data);
// 隐藏图标
this.setIconVisible(this.canvasData.hiddenBasicInfoFacilities, false);
}
/**
* 考官点击楼层
*/
public onExaminerClickFloor() {
// 创建背景图
this.createBackground(this.canvasData.selectStorey.imageUrl, this.canvasData.selectStorey.imageAngle);
// 创建楼层图形
this.createFloorShape(this.canvasData.examOriginaleveryStoreyData.data);
// 创建楼层图形
this.createFloorShape(this.canvasData.originaleveryStoreyData.data);
// 创建处置预案图形
this.createNodeShape(this.canvasData.selectPanelPoint.Data);
// 隐藏图标
this.setIconVisible(this.canvasData.hiddenBasicInfoFacilities, false);
}
}
/**
* 选择器
*/
export class Selection {
constructor(private workingArea: WorkingAreaComponent) {}
public objects: any[] = [];
public isMultiselection = false;
/**
* 返回选择器中是否包含对象
* @param obj 对象
*/
public contains(obj: any): boolean {
return this.objects.includes(obj);
}
/**
* 选定对象
* @param obj 对象
*/
public select(obj: any) {
if (!this.contains(obj)) {
this.workingArea.emit('select', obj);
this.objects.push(obj);
}
}
/**
* 取消选定对象
* @param obj 对象
*/
public deselect(obj: any) {
if (this.contains(obj)) {
this.workingArea.emit('deselect', obj);
const idx = this.objects.findIndex(x => x === obj);
this.objects.splice(idx, 1);
}
}
/**
* 选定或取消选定对象
* @param obj 对象
*/
public selectOrDeselect(obj: any) {
if (this.contains(obj)) {
this.deselect(obj);
} else {
this.select(obj);
}
}
/**
* 取消选定所有已选定对象
*/
public deselectAll() {
this.objects.forEach(item => {
this.workingArea.emit('deselect', item);
});
this.objects.splice(0, this.objects.length);
}
/**
* 取消选定所有对象后选定一个对象
* @param obj 对象
*/
public selectOne(obj: any) {
if (this.isMultiselection) {
this.selectOrDeselect(obj);
} else {
this.deselectAll();
this.select(obj);
}
}
/**
* 选定对象集合中所有对象
* @param objects 对象集合
*/
public selectAll(objects: any[]) {
this.objects.forEach(item => {
this.select(item);
});
}
}
/**
* 车辆类型
*/
export enum Type {
= 0,
= 1,
= 2,
= 3,
= 4
}