diff --git a/src/app/ui/collection-tools/collection-tools.component.html b/src/app/ui/collection-tools/collection-tools.component.html index 25b9bd6..4a43c48 100644 --- a/src/app/ui/collection-tools/collection-tools.component.html +++ b/src/app/ui/collection-tools/collection-tools.component.html @@ -62,14 +62,17 @@ <!--功能区 --> <div class="functionalDomain"> <div class='functionalDomainContent'> - <!-- H5Canvas --> - <app-working-area></app-working-area> + + <!-- H5Canvas --> + <app-working-area></app-working-area> <!-- H5Canvas --> <div class='functionalDomainLeft publicCss' [ngClass]="{'togglePanel': toggleExpandPanel==true}"> <!-- 平面图 --> <div class="planarGraph"> <div class="planarGraphHeader" (click)='togglePlanarGraph()'> + <mat-icon *ngIf="togglePlane">keyboard_arrow_up</mat-icon> + <mat-icon *ngIf="!togglePlane">keyboard_arrow_down</mat-icon> <label class="overflowText" style="font-weight: 550;">平面图</label> <label class="hover"> <mat-icon (click)='foundPanel($event)' class="matIcons">add</mat-icon> @@ -80,12 +83,24 @@ [ngClass]="{'selectSitePlan': selectSitePlanIndex==key}" (click)='selectSitePlan(item,key)'> <mat-icon *ngIf="!item.imageUrl" class="matIcons">broken_image</mat-icon> <label class="overflowText">{{item.name}}</label> - <mat-icon title="替换底图" style="float: right; margin-top: 8px;" *ngIf="selectSitePlanIndex==key" - class="matIcons">photo_size_select_actual</mat-icon> + <mat-icon title="替换底图" class="matIcons replaceBaseMap" *ngIf="selectSitePlanIndex==key">photo_size_select_actual</mat-icon> <!-- 右边定位操作栏 --> - <!-- <div id="rightOperate"> - - </div> --> + <div id="rightOperate" *ngIf="selectSitePlanIndex==key"> + <p class="functionButton"> + <mat-icon class="functionIcon bigFunctionIcon" title="上移">keyboard_arrow_up</mat-icon> + </p> + <p class="functionButton"> + <mat-icon class="functionIcon" title="编辑属性">edit</mat-icon> + <mat-icon class="functionIcon" title="删除">delete</mat-icon> + </p> + <p class="functionButton"> + <mat-icon class="functionIcon" title="旋转底图">cached</mat-icon> + <mat-icon class="functionIcon" title="复制">library_books</mat-icon> + </p> + <p class="functionButton"> + <mat-icon class="functionIcon bigFunctionIcon" title="下移">keyboard_arrow_down</mat-icon> + </p> + </div> <!-- 右边定位操作栏 --> </div> </div> @@ -94,6 +109,8 @@ <!-- 素材库 --> <div id="materialBank"> <div class="planarGraphHeader" (click)='toggleMaterial()'> + <mat-icon *ngIf="toggleMaterialBank">keyboard_arrow_up</mat-icon> + <mat-icon *ngIf="!toggleMaterialBank">keyboard_arrow_down</mat-icon> <label class="overflowText" style="font-weight: 550;">素材库</label> </div> <div style="flex: 1;overflow-y: auto;" [hidden]="!toggleMaterialBank"> @@ -117,8 +134,6 @@ </div> </div> - - </div> <div class="functionalDomainRight publicCss "> @@ -206,8 +221,9 @@ </div> </div> </div> + </div> - </div> + <!--功能区 --> </div> \ No newline at end of file diff --git a/src/app/ui/collection-tools/collection-tools.component.scss b/src/app/ui/collection-tools/collection-tools.component.scss index 1ee8caf..df34111 100644 --- a/src/app/ui/collection-tools/collection-tools.component.scss +++ b/src/app/ui/collection-tools/collection-tools.component.scss @@ -2,7 +2,7 @@ .content { width: 100%; height: 93%; - // overflow: hidden; + overflow: hidden; box-sizing: border-box; padding: 3px; display: flex; @@ -76,7 +76,6 @@ background-color: #fff; border-radius: 5px; position: absolute; - z-index: 999; height: 100%; top: 0; } @@ -104,7 +103,6 @@ } //左侧导航栏显示隐藏 .togglePanel { - z-index: -999; margin-left: -300px; transition: margin-left 0.5s; } diff --git a/src/app/ui/collection-tools/panel.scss b/src/app/ui/collection-tools/panel.scss index 37d5c60..55ccd4f 100644 --- a/src/app/ui/collection-tools/panel.scss +++ b/src/app/ui/collection-tools/panel.scss @@ -12,7 +12,7 @@ flex-direction: row; align-items: center; padding: 0 24px; - border-radius: inherit; + border-radius: 5px; font-family: Roboto, "Helvetica Neue", sans-serif; font-size: 15px; font-weight: 400; @@ -41,20 +41,44 @@ line-height: 36px; box-sizing: border-box; padding: 0 10px 0 25px; - cursor:pointer; .mat-icon { font-size: 20px; } } +.replaceBaseMap { + float: right; + margin-top: 8px; +} +.replaceBaseMap:hover { + color: #fff; +} +//hover时显示右边操作栏 +.sitePlanContent:hover { + #rightOperate { + display: block; + } +} //右边操作栏 #rightOperate{ - width: 100px; + width: 50px; height: 100px; position: absolute; - top: -36px; - right: -100px; - z-index: 999; - background-color: #999; + top: -32px; + right: -51px; + border-radius: 0 100px 100px 0; + background-color: #cdced1; + // #F0F4F7 + display: none; + .functionButton { + height: 25%; + line-height: 25px; + } + .bigFunctionIcon { + font-size: 24px; + } + .functionIcon:hover { + color: #4DA5FA; + } } //素材库溢出隐藏 @@ -63,6 +87,7 @@ display: flex; flex-direction: column; overflow: hidden; + padding-bottom: 10px; } //素材库图片flex #panelLibrary .text{ diff --git a/src/app/working-area/working-area.component.html b/src/app/working-area/working-area.component.html index 3d643df..b9f89da 100644 --- a/src/app/working-area/working-area.component.html +++ b/src/app/working-area/working-area.component.html @@ -1,14 +1 @@ -<div #content style="width:100%;height:100%;" (mousewheel)='mouseWheelHandel($event)'> - <button - (click)="this.replaceBackgroundImage('https://qntemp3.bejson.com/upload/72681686638249940.jpg?imageView2/0/w/0/h/0/format/webp')">替换背景图</button> - <button - (click)="this.createSinglePointIcon('https://qntemp3.bejson.com/upload/72681686638249940.jpg?imageView2/0/w/100/h/100/format/webp')">创建图标</button> - <button - (click)="this.replaceBackgroundImage('https://qntemp3.bejson.com/upload/72681686638249940.jpg?imageView2/0/w/0/h/0/format/webp')">创建多边形</button> - <button - (click)="this.replaceBackgroundImage('https://qntemp3.bejson.com/upload/72681686638249940.jpg?imageView2/0/w/0/h/0/format/webp')">创建多点连线</button> - <button - (click)="this.replaceBackgroundImage('https://qntemp3.bejson.com/upload/72681686638249940.jpg?imageView2/0/w/0/h/0/format/webp')">取消创建</button> - <button (click)="this.setBackgroundImageVisible(false)">隐藏背景图</button> - <button (click)="this.setBackgroundImageVisible(true)">显示背景图</button> -</div> \ No newline at end of file +<div #content style="width:100%;height:100%;" (mousewheel)='this.mouseWheelHandel($event)'></div> \ No newline at end of file diff --git a/src/app/working-area/working-area.component.ts b/src/app/working-area/working-area.component.ts index cf4ee46..cc9e81f 100644 --- a/src/app/working-area/working-area.component.ts +++ b/src/app/working-area/working-area.component.ts @@ -20,165 +20,169 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit { loader = PIXI.Loader.shared; // 根目录 backgroundImage: PIXI.Sprite; - // 影子 - shadow = new PIXI.Sprite(); - // 影子圆形 - shadowCircle = new PIXI.Graphics(); + // 单点图标影子 + singlePointIconShadow = new PIXI.Sprite(); + // 线图标影子 + lineIconShadow = new PIXI.Graphics(); + // 圆形影子 + circleShadow = new PIXI.Graphics(); // 鼠标位置 - mousePosition; - // 初始化 + mousePosition: PIXI.Point; + /// 绘画模式 + paintMode: PaintMode; + ngOnInit(): void { } - // 页面初始化之后 + ngAfterViewInit(): void { setTimeout(() => { - this.init(); + this.createCanvas(); }, 0); } - // 鼠标滑动事件 - mouseWheelHandel(event) { + /// <summary> + /// 鼠标滑动事件 + /// <summary> + public mouseWheelHandel(event) { const delX = this.mousePosition.x - this.backgroundImage.position.x; const delY = this.mousePosition.y - this.backgroundImage.position.y; - const scaleX = delX / this.backgroundImage.width; - const scaleY = delY / this.backgroundImage.height; + 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; 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.anchor.x += scaleX; - this.backgroundImage.anchor.y += scaleY; + this.backgroundImage.position.x += delX; this.backgroundImage.position.y += delY; - this.backgroundImage.children.forEach(item => { - console.log(item.position); - }); } else if (delta < 0) { if (this.backgroundImage.scale.x <= 0.1) { this.backgroundImage.scale.y = 0.1; 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.anchor.x += scaleX; - this.backgroundImage.anchor.y += scaleY; + this.backgroundImage.position.x += delX; this.backgroundImage.position.y += delY; - this.backgroundImage.children.forEach(item => { - console.log(item.position); - }); } } - // 测试按钮 - init() { - this.createCanvas(); - this.createBackgroundImage('https://qntemp3.bejson.com/upload/24797865631586900.jpg?imageView2/0/w/0/h/0/format/webp'); - this.createShadowIcon('https://qntemp3.bejson.com/upload/24797865631586900.jpg?imageView2/0/w/100/h/100/format/webp'); - this.setShadowVisible(false); - } - // 创建画布 - createCanvas(): void { + /// <summary> + /// 创建画布 + /// <summary> + 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: 0x1099bb + backgroundColor: 0x1099bb// 0xffffff }); this.content.nativeElement.appendChild(this.app.view); + + this.createBackgroundImage(); + this.createSinglePointIconShadow(); + this.createLineIconShadow(); + this.app.ticker.add((delta) => { this.mousePosition = this.app.renderer.plugins.interaction.mouse.global; - this.shadow.position = this.mousePosition; - this.shadowCircle.position = this.mousePosition; - }); - } - - // setIcon() { - // const defaultIcon = 'url(\'assets/images/avatar.jpg\'),auto'; - // this.app.renderer.plugins.interaction.cursorStyles.default = defaultIcon; - // } - // // 加载资源 - // LoadAsset(name: string, path: string) { - // this.loader.onProgress.add(() => { - // console.log(this.loader.progress); - // }); // called once per loaded/errored file - // this.loader.onError.add(() => { }); // called once per errored file - // this.loader.onLoad.add(() => { }); // called once per loaded file - // this.loader.onComplete.add(() => { - // alert('aaaaaaaa'); - // }); // called once when the queued resources all load. - // this.loader.add(name, path); - // } + this.singlePointIconShadow.position = this.mousePosition; + this.circleShadow.position = this.mousePosition; - // 创建单点图标 - createSprite(source: string, x: number, y: number, width: number, height: number, alpha: number): PIXI.Sprite { - const sprite = PIXI.Sprite.from(source); - sprite.x = x; - sprite.y = y; - sprite.width = width; - sprite.height = height; - sprite.alpha = alpha; - sprite.anchor.set(0.5); - sprite.interactive = true; - sprite.buttonMode = true; - sprite - .on('pointerdown', this.onDragStart) - .on('pointerup', this.onDragEnd) - .on('pointerupoutside', this.onDragEnd) - .on('pointermove', this.onDragMove); - this.app.stage.addChild(sprite); - sprite.setParent(this.backgroundImage); - return sprite; - } - // 拖动开始 - onDragStart(event) { - event.currentTarget.data = event.data; - event.currentTarget.alpha = 0.5; - event.currentTarget.dragging = true; - } - // 拖动结束 - onDragEnd(event) { - event.currentTarget.alpha = 1; - event.currentTarget.dragging = false; - event.currentTarget.data = null; + // this.lineIconShadow.clear(); + // this.lineIconShadow.lineStyle(1, 0xffd900, 1); + // this.lineIconShadow.lineTo(100, 100); + }); } - // 拖动移动 - onDragMove(event) { - if (event.currentTarget.dragging) { + /// <summary> + /// 创建单点图标 + /// <summary> + 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; + singlePointIcon.y = y; + singlePointIcon.width = width; + singlePointIcon.height = height; + singlePointIcon.alpha = alpha; + singlePointIcon.anchor.set(0.5); + singlePointIcon.interactive = true; + singlePointIcon + .on('mousedown', event => { + event.stopPropagation(); + console.log(event); + 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 => { + }); + this.backgroundImage.addChild(singlePointIcon); + return singlePointIcon; } - // 加载精灵图 - SetupSprite(name: string) { - const sprite = new PIXI.Sprite( - this.loader.resources[name].texture - ); - } - // 画圆 - DrawCircle(x: number): void { - this.shadowCircle.beginFill(0xFFCC5A); - this.shadowCircle.drawCircle(0, 0, x); - this.app.stage.addChild(this.shadowCircle); + /// <> + /// 多点连线 + /// <> + 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); + + const iconPoint = new PIXI.Graphics(); + iconPoint.lineStyle(0); + iconPoint.beginFill(0xFFFF0B, 1); + iconPoint.drawCircle(item.x, item.y, 15); + iconPoint.endFill(); + container.addChild(iconPoint); + }); + this.backgroundImage.addChild(container); } - // 创建背景图 - createBackgroundImage(source: string): void { - this.backgroundImage = PIXI.Sprite.from(source); + /// <summary> + /// 创建背景图 + /// <summary> + private createBackgroundImage(): void { + 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 - .on('pointerdown', event => { - if (!event.currentTarget.dragging) { + .on('mousedown', event => { + if (!event.currentTarget.dragging && event.currentTarget.name === this.backgroundImage.name) { event.currentTarget.data = event.data; // this.oldGroup = this.parentGroup; // this.parentGroup = dragGroup; @@ -188,22 +192,36 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit { event.currentTarget.dragPoint = event.data.getLocalPosition(event.currentTarget.parent); event.currentTarget.dragPoint.x -= event.currentTarget.x; event.currentTarget.dragPoint.y -= event.currentTarget.y; + // tslint:disable-next-line: max-line-length + // 点击背景创建图标 + const pos = this.backgroundImage.toLocal(this.mousePosition); + switch (this.paintMode) { + case PaintMode.PaintEnd: + console.log(this.backgroundImage.toLocal(this.mousePosition)); + break; + case PaintMode.SinglePointIcon: + this.createSinglePointIcon(this.singlePointIconShadow.texture, pos.x, pos.y, 32, 32, 1); + 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)]); + break; + case PaintMode.PolygonIcon: + break; + } } }) - .on('pointerup', event => { - if (event.currentTarget.dragging) { + .on('mouseup', event => { + if (event.currentTarget.dragging && event.currentTarget.name === this.backgroundImage.name) { event.currentTarget.dragging = false; // this.parentGroup = this.oldGroup; // event.currentTarget.scale.x /= 1.1; // event.currentTarget.scale.y /= 1.1; event.currentTarget.data = null; - console.log('创建图片'); - // tslint:disable-next-line: max-line-length - this.createSprite('https://qntemp3.bejson.com/upload/72681686638249940.jpg?imageView2/0/w/100/h/100/format/webp', this.mousePosition.x, this.mousePosition.y, 64, 64, 1); } }) - .on('pointerupoutside', event => { - if (event.currentTarget.dragging) { + .on('mouseupoutside', event => { + if (event.currentTarget.dragging && event.currentTarget.name === this.backgroundImage.name) { event.currentTarget.dragging = false; // this.parentGroup = this.oldGroup; // event.currentTarget.scale.x /= 1.1; @@ -211,53 +229,115 @@ export class WorkingAreaComponent implements OnInit, AfterViewInit { event.currentTarget.data = null; } }) - .on('pointermove', event => { - if (event.currentTarget.dragging) { + .on('mousemove', event => { + if (event.currentTarget.dragging && event.currentTarget.name === this.backgroundImage.name) { 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; } + }).on('rightclick', event => { + event.stopPropagation(); + this.cancelPaint(); + }); this.app.stage.addChild(this.backgroundImage); } - - addShadow(obj) { - const graphics = new PIXI.Graphics(); - // Circle - graphics.lineStyle(0); - graphics.beginFill(0xDE3249, 1); - graphics.drawCircle(100, 250, 50); - graphics.endFill(); - obj.addChild(graphics); -} - // 设置背景显示状态 - setBackgroundImageVisible(value: boolean): void { - this.backgroundImage.visible = value; - } - // 替换背景图 - replaceBackgroundImage(source: string): void { + /// <summary> + /// 替换背景图 + /// 参数{source:string} 可以是一个url地址,也可以是本地assets下的一个图片路径 + /// <summary> + public changeBackgroundImage(source: string): void { this.backgroundImage.texture = PIXI.Texture.from(source); + this.backgroundImage.visible = true; + } + /// <summary> + /// 创建单点图标影子 + /// <summary> + private createSinglePointIconShadow(): void { + this.singlePointIconShadow = PIXI.Sprite.from('assets/images/noImg.png'); + this.singlePointIconShadow.width = 32; + this.singlePointIconShadow.height = 32; + this.singlePointIconShadow.alpha = 0.5; + this.singlePointIconShadow.anchor.set(0.5); + this.singlePointIconShadow.visible = false; + this.app.stage.addChild(this.singlePointIconShadow); } - // 创建影子图标 - createShadowIcon(source: string): void { - this.shadow = PIXI.Sprite.from(source); - this.shadow.alpha = 0.5; - this.shadow.anchor.set(0.5); - this.app.stage.addChild(this.shadow); + /// <summary> + /// 改变单点图标影子 + /// <summary> + private changeSinglePointIconShadow(source: string): void { + this.singlePointIconShadow.texture = PIXI.Texture.from(source); + this.singlePointIconShadow.visible = true; } - // 设置影子图标显示状态 - setShadowVisible(value: boolean): void { - this.shadow.visible = value; + /// <> + /// 创建线图标影子 + /// <> + private createLineIconShadow() { + this.app.stage.addChild(this.lineIconShadow); } - // 替换影子图片 - replaceShadow(source: string): void { - this.shadow.texture = PIXI.Texture.from(source); + /// <summary> + /// 开始绘画单点图标 + /// <summary> + public beginPaintSinglePointIcon(source: string): void { + this.cancelPaint(); + this.paintMode = PaintMode.SinglePointIcon; + this.changeSinglePointIconShadow(source); } - // 创建单点图标 - createSinglePointIcon(source: string): void { - this.DrawCircle(5); - // this.setShadowVisible(true); - // this.addShadow(this.shadow); - // this.replaceShadow(source); + // 开始绘画多边形 + public beginPaintPolygonIcon(source: string): void { + this.cancelPaint(); + this.paintMode = PaintMode.PolygonIcon; + } + // 开始绘画线 + public beginPaintLineIcon(source: string): void { + this.cancelPaint(); + this.paintMode = PaintMode.LineIcon; + this.changeSinglePointIconShadow(source); + // this.lineIconShadow.lineStyle(1, 0xffd900, 1); + } + /// <summary> + /// 取消绘画 + /// <summary> + private cancelPaint(): void { + switch (this.paintMode) { + case PaintMode.PaintEnd: + break; + case PaintMode.SinglePointIcon: + this.paintMode = PaintMode.PaintEnd; + this.singlePointIconShadow.visible = false; + break; + case PaintMode.LineIcon: + this.paintMode = PaintMode.PaintEnd; + this.singlePointIconShadow.visible = false; + break; + case PaintMode.PolygonIcon: + this.paintMode = PaintMode.PaintEnd; + break; + } + } + /// <summary> + /// 画圆 + /// <summary> + 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, + PaintingLineIcon, + PolygonIcon, + PaintEnd, }