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.
244 lines
10 KiB
244 lines
10 KiB
4 years ago
|
import { WorkingAreaComponent } from '../working-area.component';
|
||
|
import { GameMode } from './gameMode';
|
||
|
import * as PIXI from 'pixi.js';
|
||
|
|
||
|
/**
|
||
|
* 多边形
|
||
|
*/
|
||
|
export class PolygonIcon extends PIXI.Container {
|
||
|
public pointsData: PIXI.Point[];
|
||
|
public pointsGraphics: PIXI.Graphics[] = [];
|
||
|
public polygonGraphics: PIXI.Graphics = new PIXI.Graphics();
|
||
|
public polygonLineGraphics: PIXI.Graphics = new PIXI.Graphics();
|
||
|
style = new PIXI.TextStyle({
|
||
|
fontFamily: 'Arial',
|
||
|
fontSize: 18,
|
||
|
fontStyle: 'normal',
|
||
|
fontWeight: 'bold',
|
||
|
fill: ['#000000'],
|
||
|
stroke: '#ffffff',
|
||
|
strokeThickness: 3,
|
||
|
dropShadow: true,
|
||
|
dropShadowColor: '#000000',
|
||
|
dropShadowBlur: 3,
|
||
|
dropShadowAngle: Math.PI / 6,
|
||
|
dropShadowDistance: 1,
|
||
|
wordWrap: false,
|
||
|
wordWrapWidth: 100,
|
||
|
});
|
||
|
|
||
|
public text = new PIXI.Text(this.assetData.Name
|
||
|
+ '\r\n'
|
||
|
+ this.assetData.PropertyInfos.find(item => item.PropertyName === '名称/编号')?.PropertyValue, this.style);
|
||
|
/**
|
||
|
*
|
||
|
* @param points 点集合
|
||
|
*/
|
||
|
constructor(public assetData: any, private workingArea: WorkingAreaComponent) {
|
||
|
super();
|
||
|
this.name = this.assetData.Id;
|
||
|
this.x = this.assetData.Point.x;
|
||
|
this.y = this.assetData.Point.y;
|
||
|
this.pointsData = this.assetData.MultiPoint;
|
||
|
this.workingArea.backgroundImage.addChild(this);
|
||
|
this.sortableChildren = true;
|
||
|
// 画点
|
||
|
this.pointsData.forEach((item, index, array) => {
|
||
|
const iconPoint = new PIXI.Graphics();
|
||
|
iconPoint.lineStyle(1, 0xFFBD01, 1);
|
||
|
iconPoint.beginFill(0xFFFFFF, 1);
|
||
|
iconPoint.drawCircle(0, 0, 15);
|
||
|
iconPoint.x = item.x;
|
||
|
iconPoint.y = item.y;
|
||
|
iconPoint.endFill();
|
||
|
iconPoint.visible = false;
|
||
|
this.pointsGraphics.push(iconPoint);
|
||
|
this.addChild(iconPoint);
|
||
|
});
|
||
|
// 填充多边形
|
||
|
|
||
|
const color: number = this.assetData.Color.substring(0, 7).replace('#', '0x');
|
||
|
const angle: number = parseInt(this.assetData.Color.substring(7), 16) / 255;
|
||
|
this.polygonGraphics.beginFill(color, angle);
|
||
|
this.polygonGraphics.drawPolygon(this.getPoints());
|
||
|
this.polygonGraphics.endFill();
|
||
|
this.addChild(this.polygonGraphics);
|
||
|
// 画多边形
|
||
|
this.polygonLineGraphics.lineStyle(5, 0xFFBD01, 1);
|
||
|
this.polygonLineGraphics.drawPolygon(this.getPoints());
|
||
|
this.polygonLineGraphics.closePath();
|
||
|
this.addChild(this.polygonLineGraphics);
|
||
|
|
||
|
this.text.anchor.set(0.5);
|
||
|
this.text.position = this.calculatePolygonGravityCenter(this.pointsData);
|
||
|
// console.log(this.calculatePolygonGravityCenter(this.pointsData));
|
||
|
this.polygonGraphics.addChild(this.text);
|
||
|
// 添加圆点事件
|
||
|
this.pointsGraphics.forEach((item, index, array) => {
|
||
|
item.interactive = true;
|
||
|
item.zIndex = 1;
|
||
|
item.on('mousedown', event => {
|
||
|
event.stopPropagation();
|
||
|
if (this.workingArea.allowEdit && this.assetData.GameMode === this.workingArea.canvasData.gameMode) {
|
||
|
event.currentTarget.data = event.data;
|
||
|
event.currentTarget.alpha = 0.5;
|
||
|
event.currentTarget.dragging = true;
|
||
|
}
|
||
|
})
|
||
|
.on('mouseup', event => {
|
||
|
if (event.currentTarget.dragging) {
|
||
|
event.currentTarget.alpha = 1;
|
||
|
event.currentTarget.dragging = false;
|
||
|
event.currentTarget.data = null;
|
||
|
}
|
||
|
})
|
||
|
.on('mouseupoutside', event => {
|
||
|
if (event.currentTarget.dragging) {
|
||
|
event.currentTarget.alpha = 1;
|
||
|
event.currentTarget.dragging = false;
|
||
|
event.currentTarget.data = null;
|
||
|
}
|
||
|
})
|
||
|
.on('mousemove', event => {
|
||
|
if (event.currentTarget.dragging) {
|
||
|
const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
|
||
|
event.currentTarget.x = newPosition.x;
|
||
|
event.currentTarget.y = newPosition.y;
|
||
|
|
||
|
this.assetData.MultiPoint[index].x = newPosition.x;
|
||
|
this.assetData.MultiPoint[index].y = newPosition.y;
|
||
|
this.workingArea.canvasData.isChange = true;
|
||
|
// 填充多边形
|
||
|
this.polygonGraphics.clear();
|
||
|
this.polygonGraphics.beginFill(color, angle);
|
||
|
this.polygonGraphics.drawPolygon(this.getPoints());
|
||
|
this.polygonGraphics.endFill();
|
||
|
// 画多边形
|
||
|
this.polygonLineGraphics.clear();
|
||
|
this.polygonLineGraphics.lineStyle(5, 0xFFBD01, 1);
|
||
|
this.polygonLineGraphics.drawPolygon(this.getPoints());
|
||
|
this.polygonLineGraphics.closePath();
|
||
|
|
||
|
this.text.position = this.calculatePolygonGravityCenter(this.pointsData);
|
||
|
}
|
||
|
})
|
||
|
.on('rightclick', event => {
|
||
|
});
|
||
|
});
|
||
|
// 添加选中事件
|
||
|
this.polygonGraphics.interactive = true;
|
||
|
this.polygonGraphics
|
||
|
.on('mousedown', event => {
|
||
|
event.stopPropagation();
|
||
|
this.workingArea.selection.selectOne(this);
|
||
|
if (this.workingArea.allowEdit && this.assetData.GameMode === this.workingArea.canvasData.gameMode) {
|
||
|
event.currentTarget.parent.data = event.data;
|
||
|
event.currentTarget.parent.alpha = 0.5;
|
||
|
event.currentTarget.parent.dragging = true;
|
||
|
|
||
|
event.currentTarget.parent.dragPoint = event.data.getLocalPosition(event.currentTarget.parent.parent);
|
||
|
event.currentTarget.parent.dragPoint.x -= event.currentTarget.parent.x;
|
||
|
event.currentTarget.parent.dragPoint.y -= event.currentTarget.parent.y;
|
||
|
}
|
||
|
})
|
||
|
.on('mouseup', event => {
|
||
|
if (event.currentTarget.parent.dragging) {
|
||
|
event.currentTarget.parent.alpha = 1;
|
||
|
event.currentTarget.parent.dragging = false;
|
||
|
event.currentTarget.parent.data = null;
|
||
|
}
|
||
|
})
|
||
|
.on('mouseupoutside', event => {
|
||
|
if (event.currentTarget.parent.dragging) {
|
||
|
event.currentTarget.parent.alpha = 1;
|
||
|
event.currentTarget.parent.dragging = false;
|
||
|
event.currentTarget.parent.data = null;
|
||
|
}
|
||
|
})
|
||
|
.on('mousemove', event => {
|
||
|
if (event.currentTarget.parent.dragging) {
|
||
|
const newPosition = event.currentTarget.parent.data.getLocalPosition(event.currentTarget.parent.parent);
|
||
|
event.currentTarget.parent.x = newPosition.x - event.currentTarget.parent.dragPoint.x;
|
||
|
event.currentTarget.parent.y = newPosition.y - event.currentTarget.parent.dragPoint.y;
|
||
|
|
||
|
this.assetData.Point = new PIXI.Point(this.x, this.y);
|
||
|
this.workingArea.canvasData.isChange = true;
|
||
|
}
|
||
|
})
|
||
|
.on('rightclick', event => {
|
||
|
// this.workingArea.selection.deselectAll();
|
||
|
});
|
||
|
// // 缩放
|
||
|
// this.workingArea.on('backgroundScale', data => {
|
||
|
// const scale = 1 / data;
|
||
|
// this.text.scale.set(scale);
|
||
|
// });
|
||
|
}
|
||
|
/**
|
||
|
* 设置点显示状态
|
||
|
* @param value 显示状态
|
||
|
*/
|
||
|
public setPointVisiable(value: boolean) {
|
||
|
this.pointsGraphics.forEach((item) => {
|
||
|
item.visible = value;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public calculatePolygonGravityCenter(points: PIXI.Point[]) {
|
||
|
let area = 0.0; // 多边形面积
|
||
|
let gravityLat = 0.0; // 重心点 latitude
|
||
|
let gravityLng = 0.0; // 重心点 longitude
|
||
|
points.forEach((item, index) => {
|
||
|
// 1
|
||
|
const lat = item.x;
|
||
|
const lng = item.y;
|
||
|
const nextLat = points[(index + 1) % points.length].x;
|
||
|
const nextLng = points[(index + 1) % points.length].y;
|
||
|
// 2
|
||
|
const tempArea = (nextLat * lng - nextLng * lat) / 2.0;
|
||
|
// 3
|
||
|
area += tempArea;
|
||
|
// 4
|
||
|
gravityLat += tempArea * (lat + nextLat) / 3;
|
||
|
gravityLng += tempArea * (lng + nextLng) / 3;
|
||
|
});
|
||
|
// 5
|
||
|
gravityLat = gravityLat / area;
|
||
|
gravityLng = gravityLng / area;
|
||
|
|
||
|
return new PIXI.Point(gravityLat, gravityLng);
|
||
|
}
|
||
|
/**
|
||
|
* 获取点集合
|
||
|
*/
|
||
|
public getPoints(): PIXI.Point[] {
|
||
|
const points: PIXI.Point[] = [];
|
||
|
this.pointsGraphics.forEach(item => {
|
||
|
points.push(item.position);
|
||
|
});
|
||
|
return points;
|
||
|
}
|
||
|
/**
|
||
|
* 设置名称显示
|
||
|
* @param value true/false 显示/隐藏
|
||
|
* @param mode BasicInformation = 0 基本信息
|
||
|
* Assignment想定作业 = 1 想定作业
|
||
|
*/
|
||
|
public setNameVisible(value: boolean, mode: GameMode) {
|
||
|
if (this.assetData.GameMode === mode) {
|
||
|
this.text.visible = value;
|
||
|
}
|
||
|
}
|
||
|
public refresh() {
|
||
|
this.text.text = this.assetData.Name
|
||
|
+ '\r\n'
|
||
|
+ this.assetData.PropertyInfos.find(item => item.PropertyName === '名称/编号')?.PropertyValue;
|
||
|
// 填充多边形
|
||
|
const color: number = this.assetData.Color.substring(0, 7).replace('#', '0x');
|
||
|
const angle: number = parseInt(this.assetData.Color.substring(7), 16) / 255;
|
||
|
this.polygonGraphics.clear();
|
||
|
this.polygonGraphics.beginFill(color, angle);
|
||
|
this.polygonGraphics.drawPolygon(this.getPoints());
|
||
|
this.polygonGraphics.endFill();
|
||
|
}
|
||
|
}
|