@ -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 ) ;
}
}
}
}
}