邵佳豪 5 years ago
parent
commit
372a923f67
  1. 458
      src/app/working-area/working-area.component.ts

458
src/app/working-area/working-area.component.ts

@ -15,21 +15,21 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit {
content: ElementRef;
// 画布程序
app: PIXI.Application;
public app: PIXI.Application;
// 加载器
loader = PIXI.Loader.shared;
public loader = PIXI.Loader.shared;
// 根目录
backgroundImage: PIXI.Sprite;
public backgroundImage: PIXI.Sprite;
// 单点图标影子
singlePointIconShadow = new PIXI.Sprite();
public singlePointIconShadow = new PIXI.Sprite();
// 线图标影子
lineIconShadow = new PIXI.Graphics();
public lineIconShadow = new PIXI.Graphics();
// 圆形影子
circleShadow = new PIXI.Graphics();
public circleShadow = new PIXI.Graphics();
// 鼠标位置
mousePosition: PIXI.Point;
public mousePosition: PIXI.Point;
/// 绘画模式
paintMode: PaintMode;
public paintMode: PaintMode;
ngOnInit(): void {
@ -104,9 +104,15 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit {
// this.lineIconShadow.lineTo(100, 100);
});
}
/// <summary>
/// 创建单点图标
/// <summary>
/**
*
* @param source
* @param x
* @param y
* @param width
* @param height
* @param alpha
*/
private createSinglePointIcon(source: PIXI.Texture, x: number, y: number, width: number, height: number, alpha: number): PIXI.Sprite {
const singlePointIcon = new PIXI.Sprite(source);
singlePointIcon.x = x;
@ -136,9 +142,9 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit {
})
.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;
const newPosition = event.currentTarget.data.getLocalPosition(event.currentTarget.parent);
event.currentTarget.x = newPosition.x;
event.currentTarget.y = newPosition.y;
}
})
.on('rightclick', event => {
@ -152,27 +158,111 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit {
/// <>
private createLineIcon(source: PIXI.Texture, x: number, y: number, points: PIXI.Point[]) {
const container = new PIXI.Container();
container.x = x;
container.y = y;
points.forEach(item => {
const icon = new PIXI.TilingSprite(source, 100, 64);
icon.anchor.set(0, 0.5);
icon.x = item.x;
icon.y = item.y;
container.addChild(icon);
container.name = '多点连线';
// 画点
points.forEach((item, index, array) => {
const iconPoint = new PIXI.Graphics();
iconPoint.lineStyle(0);
iconPoint.beginFill(0xFFFF0B, 1);
iconPoint.drawCircle(item.x, item.y, 15);
iconPoint.drawCircle(0, 0, 15);
iconPoint.x = item.x;
iconPoint.y = item.y;
iconPoint.endFill();
container.addChild(iconPoint);
});
// 画线图标
for (let i = 0, count = points.length - 1; i < count; i++) {
const pointA = points[i];
const pointB = points[i + 1];
const angle = Math.atan2((pointB.y - pointA.y), (pointB.x - pointA.x)) * (180 / Math.PI);
const a = pointB.x - pointA.x;
const b = pointB.y - pointA.y;
const distance = Math.sqrt(a * a + b * b);
const icon = new PIXI.TilingSprite(source, distance, 64);
icon.anchor.set(0, 0.5);
icon.x = pointA.x;
icon.y = pointA.y;
icon.angle = angle;
container.addChild(icon);
}
this.backgroundImage.addChild(container);
// 添加事件
container.children.forEach(item => {
if (item instanceof PIXI.Graphics) {
item.interactive = true;
item.on('mousedown', event => {
event.stopPropagation();
event.currentTarget.data = event.data;
event.currentTarget.alpha = 0.5;
event.currentTarget.dragging = true;
})
.on('mouseup', event => {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
})
.on('mouseupoutside', event => {
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;
}
})
.on('rightclick', event => {
});
} else if (item instanceof PIXI.TilingSprite) {
item.interactive = true;
item.on('mousedown', event => {
event.stopPropagation();
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 => {
event.currentTarget.parent.alpha = 1;
event.currentTarget.parent.dragging = false;
event.currentTarget.parent.data = null;
})
.on('mouseupoutside', event => {
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;
}
})
.on('rightclick', event => {
});
}
});
}
/// <summary>
/// 创建背景图
/// <summary>
/**
*
* @param texture
* @param points
*/
private createLineIconTest(texture: PIXI.Texture, points: PIXI.Point[]) {
const icon = new MultipointIcon(texture, points);
this.backgroundImage.addChild(icon);
}
/**
*
*/
private createBackgroundImage(): void {
this.backgroundImage = PIXI.Sprite.from('assets/images/noImg.png');
this.backgroundImage.anchor.set(0.5);
@ -204,7 +294,9 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit {
break;
case PaintMode.LineIcon:
// tslint:disable-next-line: max-line-length
this.createLineIcon(this.singlePointIconShadow.texture, pos.x, pos.y, [new PIXI.Point(0, 0), new PIXI.Point(100, 0), new PIXI.Point(100, 100)]);
// this.createLineIcon(this.singlePointIconShadow.texture, 0, 0, [new PIXI.Point(0, -100), new PIXI.Point(100, 0), new PIXI.Point(0, 100)]);
// tslint:disable-next-line: max-line-length
this.createLineIconTest(this.singlePointIconShadow.texture, [new PIXI.Point(0, -100), new PIXI.Point(100, 0), new PIXI.Point(0, 100), new PIXI.Point(-100, 0)]);
break;
case PaintMode.PolygonIcon:
break;
@ -242,17 +334,26 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit {
});
this.app.stage.addChild(this.backgroundImage);
}
/// <summary>
/// 替换背景图
/// 参数{source:string} 可以是一个url地址,也可以是本地assets下的一个图片路径
/// <summary>
public changeBackgroundImage(source: string): void {
this.backgroundImage.texture = PIXI.Texture.from(source);
/**
*
* @param imageUri url地址,assets下的一个图片路径
* @param imageAngle
*/
public changeBackgroundImage(imageUri: string, imageAngle: number): void {
this.backgroundImage.texture = PIXI.Texture.from(imageUri);
this.backgroundImage.angle = imageAngle;
this.backgroundImage.visible = true;
}
/// <summary>
/// 创建单点图标影子
/// <summary>
/**
*
* @param imageAngle
*/
public setBackgroundAngle(imageAngle: number) {
this.backgroundImage.angle = imageAngle;
}
/**
*
*/
private createSinglePointIconShadow(): void {
this.singlePointIconShadow = PIXI.Sprite.from('assets/images/noImg.png');
this.singlePointIconShadow.width = 32;
@ -262,43 +363,50 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit {
this.singlePointIconShadow.visible = false;
this.app.stage.addChild(this.singlePointIconShadow);
}
/// <summary>
/// 改变单点图标影子
/// <summary>
private changeSinglePointIconShadow(source: string): void {
this.singlePointIconShadow.texture = PIXI.Texture.from(source);
/**
*
* @param uri
*/
private changeSinglePointIconShadow(uri: string): void {
this.singlePointIconShadow.texture = PIXI.Texture.from(uri);
this.singlePointIconShadow.visible = true;
}
/// <>
/// 创建线图标影子
/// <>
/**
* 线
*/
private createLineIconShadow() {
this.app.stage.addChild(this.lineIconShadow);
}
/// <summary>
/// 开始绘画单点图标
/// <summary>
public beginPaintSinglePointIcon(source: string): void {
/**
*
* @param imageUri
*/
public beginPaintSinglePointIcon(imageUri: string): void {
this.cancelPaint();
this.paintMode = PaintMode.SinglePointIcon;
this.changeSinglePointIconShadow(source);
this.changeSinglePointIconShadow(imageUri);
}
// 开始绘画多边形
public beginPaintPolygonIcon(source: string): void {
/**
*
*/
public beginPaintPolygonIcon(): void {
this.cancelPaint();
this.paintMode = PaintMode.PolygonIcon;
}
// 开始绘画线
public beginPaintLineIcon(source: string): void {
/**
*
* @param imageUri
*/
public beginPaintLineIcon(imageUri: string): void {
this.cancelPaint();
this.paintMode = PaintMode.LineIcon;
this.changeSinglePointIconShadow(source);
this.changeSinglePointIconShadow(imageUri);
// this.lineIconShadow.lineStyle(1, 0xffd900, 1);
}
/// <summary>
/// 取消绘画
/// <summary>
/**
*
*/
private cancelPaint(): void {
switch (this.paintMode) {
case PaintMode.PaintEnd:
@ -316,24 +424,25 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit {
break;
}
}
/// <summary>
/// 画圆
/// <summary>
/**
*
* @param x
*/
paintShadowCircle(x: number): void {
this.circleShadow.beginFill(0xFFCC5A);
this.circleShadow.drawCircle(0, 0, x);
this.app.stage.addChild(this.circleShadow);
}
/// <summary>
/// 取消画圆
/// <summary>
/**
*
*/
cancelPaintShadowCircle(): void {
this.app.stage.removeChild(this.circleShadow);
}
}
/// <summary>
/// 绘制模式
/// <summary>
/**
*
*/
enum PaintMode {
SinglePointIcon,
LineIcon,
@ -341,3 +450,218 @@ enum PaintMode {
PolygonIcon,
PaintEnd,
}
/**
* 线
*/
class MultipointIcon extends PIXI.Container {
public pointsData: PIXI.Point[];
public pointsGraphics: PIXI.Graphics[] = [];
public iconsTilingSprite: PIXI.TilingSprite[] = [];
/**
*
* @param texture
* @param points
*/
constructor(texture: PIXI.Texture, points: PIXI.Point[]) {
super();
this.pointsData = points;
// 画线图标
for (let i = 0, count = this.pointsData.length - 1; i < count; i++) {
const pointA = this.pointsData[i];
const pointB = this.pointsData[i + 1];
const angle = Math.atan2((pointB.y - pointA.y), (pointB.x - pointA.x)) * (180 / Math.PI);
const a = pointB.x - pointA.x;
const b = pointB.y - pointA.y;
const distance = Math.sqrt(a * a + b * b);
const icon = new PIXI.TilingSprite(texture, distance, 64);
icon.anchor.set(0, 0.5);
icon.x = pointA.x;
icon.y = pointA.y;
icon.angle = angle;
this.iconsTilingSprite.push(icon);
this.addChild(icon);
}
// 画点
this.pointsData.forEach((item, index, array) => {
const iconPoint = new PIXI.Graphics();
iconPoint.lineStyle(0);
iconPoint.beginFill(0xFFFF0B, 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);
});
// 添加圆点事件
this.pointsGraphics.forEach((item, index, array) => {
item.interactive = true;
item.on('mousedown', event => {
event.stopPropagation();
event.currentTarget.data = event.data;
event.currentTarget.alpha = 0.5;
event.currentTarget.dragging = true;
})
.on('mouseup', event => {
event.currentTarget.alpha = 1;
event.currentTarget.dragging = false;
event.currentTarget.data = null;
})
.on('mouseupoutside', event => {
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;
if (index === 0) {// 第一个点
this.iconsTilingSprite[index].x = newPosition.x;
this.iconsTilingSprite[index].y = newPosition.y;
const pointA = array[index];
const pointB = array[index + 1];
const angle = Math.atan2((pointB.y - pointA.y), (pointB.x - pointA.x)) * (180 / Math.PI);
const a = pointB.x - pointA.x;
const b = pointB.y - pointA.y;
const distance = Math.sqrt(a * a + b * b);
this.iconsTilingSprite[index].angle = angle;
this.iconsTilingSprite[index].width = distance;
} else if (index < array.length - 1) {// 不是第一个点,也不是最后一个点
this.iconsTilingSprite[index].x = newPosition.x;
this.iconsTilingSprite[index].y = newPosition.y;
const pointA = array[index]; // 当前点
const pointB = array[index + 1]; // 后一个点
const pointC = array[index - 1]; // 前一个点
const angle = Math.atan2((pointB.y - pointA.y), (pointB.x - pointA.x)) * (180 / Math.PI);
const a = pointB.x - pointA.x;
const b = pointB.y - pointA.y;
const distance = Math.sqrt(a * a + b * b);
this.iconsTilingSprite[index].angle = angle;
this.iconsTilingSprite[index].width = distance;
const angleC = Math.atan2((pointA.y - pointC.y), (pointA.x - pointC.x)) * (180 / Math.PI);
const aC = pointA.x - pointC.x;
const bC = pointA.y - pointC.y;
const distanceC = Math.sqrt(aC * aC + bC * bC);
this.iconsTilingSprite[index - 1].angle = angleC;
this.iconsTilingSprite[index - 1].width = distanceC;
} else if (index === array.length - 1) { // 最后一个点
const pointA = array[index]; // 当前点
const pointC = array[index - 1]; // 前一个点
const angleC = Math.atan2((pointA.y - pointC.y), (pointA.x - pointC.x)) * (180 / Math.PI);
const aC = pointA.x - pointC.x;
const bC = pointA.y - pointC.y;
const distanceC = Math.sqrt(aC * aC + bC * bC);
this.iconsTilingSprite[index - 1].angle = angleC;
this.iconsTilingSprite[index - 1].width = distanceC;
}
}
})
.on('rightclick', event => {
});
});
// 添加选中事件
this.iconsTilingSprite.forEach((item, index, array) => {
item.interactive = true;
item.on('mousedown', event => {
event.stopPropagation();
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;
this.setPointVisiable(true);
})
.on('mouseup', event => {
event.currentTarget.parent.alpha = 1;
event.currentTarget.parent.dragging = false;
event.currentTarget.parent.data = null;
})
.on('mouseupoutside', event => {
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;
}
})
.on('rightclick', event => {
});
});
}
/**
*
* @param value
*/
public setPointVisiable(value: boolean) {
this.pointsGraphics.forEach((item) => {
item.visible = value;
});
}
}
interface IEventData {
// 事件唯一ID
uuid: number;
callback: (data: any) => void;
}
/**
*
*/
export default class Event {
public static eventUuid = 0;
public static eventList: { [eventName: string]: IEventData[] } = {};
public static register(eventName: string, callback: (data: any) => void): number {
this.eventUuid = this.eventUuid + 1;
if (this.eventList[eventName] === undefined) {
this.eventList[eventName] = [];
}
this.eventList[eventName][this.eventUuid] = { uuid: this.eventUuid, callback };
return this.eventUuid;
}
public static unregister(eventName: string, tag: number) {
if (tag == null) {
this.eventList[eventName] = undefined;
} else {
if (this.eventList[eventName] !== undefined && this.eventList[eventName][tag] !== undefined) {
this.eventList[eventName][tag] = undefined;
}
}
}
public static dispatch(eventName: string, data: any) {
const eventList: IEventData[] = this.eventList[eventName];
if (eventList !== undefined) {
for (const key in eventList) {
if (eventList[key].callback !== undefined) {
eventList[key].callback(data);
}
}
}
}
}

Loading…
Cancel
Save