diff --git a/src/app/canvas-share-data.service.ts b/src/app/canvas-share-data.service.ts index 52f72dd..b416c1e 100644 --- a/src/app/canvas-share-data.service.ts +++ b/src/app/canvas-share-data.service.ts @@ -71,7 +71,7 @@ export class CanvasShareDataService { public getLinkCarName(car: any): any[] { const linkCar = []; car.assetData.Pipelines.forEach(pipeline => { - const icon = pipeline.assetData.LinkedObjects.find(i => i.assetData !== car); + const icon = pipeline.assetData.LinkedObjects.find(i => i !== car); if (icon.assetData.Type === 1) { linkCar.push(icon.assetData.Name); } @@ -82,9 +82,9 @@ export class CanvasShareDataService { public getWaterOccupyName(car: any): any[] { const waterOccupy = []; car.assetData.Pipelines.forEach(pipeline => { - const icon = pipeline.assetData.LinkedObjects.find(i => i.assetData !== car); + const icon = pipeline.assetData.LinkedObjects.find(i => i !== car); if (icon.assetData.Type === 0) { - car.assetData.WaterOccupy.push(icon.assetData.Name); + waterOccupy.push(icon.assetData.Name); } }); return waterOccupy; diff --git a/src/app/ui/collection-tools/collection-tools.component.html b/src/app/ui/collection-tools/collection-tools.component.html index f2f933b..8069051 100644 --- a/src/app/ui/collection-tools/collection-tools.component.html +++ b/src/app/ui/collection-tools/collection-tools.component.html @@ -112,36 +112,36 @@ - -
-
- 总平面图 -
-
- {{item.name}} -
- +
+
+ 总平面图 +
+
+ {{item.name}} +
+ -
+
--> +
@@ -287,8 +287,39 @@
-
+
+ + +
+
+ + +
+
+
+
+
+ + + + +
keyboard_arrow_up
+
+
+
+ 节点详情 +
+
+ 注意事项 +
+
expand_more
+
+
+
{{canvasData.selectPanelPointBaseData.description}}
+
{{canvasData.selectPanelPointBaseData.notes}}
+
+
@@ -492,21 +523,7 @@
- + diff --git a/src/app/ui/collection-tools/collection-tools.component.scss b/src/app/ui/collection-tools/collection-tools.component.scss index b7d3ef5..0681dde 100644 --- a/src/app/ui/collection-tools/collection-tools.component.scss +++ b/src/app/ui/collection-tools/collection-tools.component.scss @@ -230,6 +230,115 @@ } .canvas{ flex: 5; + .closebottombtn{ + width: 30px; + vertical-align: sub; + } + .openbottombtn{ + width: 30px; + color: white; + text-align: center; + height: 30px; + line-height: 30px; + vertical-align: sub; + position: absolute; + left: 5px; + bottom: 5px; + background-color:rgba(2, 44, 73, 0.9); + } + //打开时 + .openBottom{ + margin-bottom: 0; + transition: margin-bottom 1s; + } + //关闭 + .closeBottom{ + margin-bottom: -300px!important; + transition: margin-bottom 1s; + } + //右侧 楼层UI + .rightStorey { + width: 100px; + height: 250px; + position: absolute; + left: 0; + top: 50%; + margin-top: -200px; + z-index: 9999; + display: flex; + flex-direction: column; + background-color:rgba(2, 44, 73, 0.9); + color: #fff; + font-weight: 300; + >div {text-align: center; line-height: 25px;} + } + .showRightStorey { + position: absolute; + right: 0; + top: 50%; + margin-top: -13px; + z-index: 9999; + width: 26px; + height: 26px; + line-height: 26px; + text-align: center; + background-color:rgba(2, 44, 73, 0.9); + color: #fff; + } + //打开关闭右侧 楼层 + .openRight { + margin-right: 0px; + transition: margin-right 0.5s; + } + .closeRight { + margin-right: -300px; + transition: margin-right 0.5s; + } + .canvasbottomCss{ + margin-bottom: 0; + transition: margin-bottom 0.5s; + position: absolute; + bottom: 0; + width: 100%; + height: 200px; + display: flex; + flex-direction: column; + .title{ + border-bottom: 1px solid #30bbec; + flex: 1; + div{ + cursor: pointer; + background-color: rgba(2, 44, 73, 0.9); + width: 120px; + height: 30px; + line-height: 35px; + text-align: center; + margin-right: 10px; + color: white; + font-style: italic; + font-size:18px; + + } + .closebottombtn{ + width: 30px; + vertical-align: sub; + } + .detailsAndattentBtn{ + background-color: #ed863b; + } + } + .body{ + flex: 10; + background-color:rgba(2, 44, 73, 0.9); + div{ + color: #d0e0f4; + font-size: 16px; + letter-spacing:5px; + margin: 5px 0 0 8px; + } + } + + } } .functionalDomainRight { color: white; diff --git a/src/app/ui/collection-tools/collection-tools.component.ts b/src/app/ui/collection-tools/collection-tools.component.ts index 0ab1dfe..6821e07 100644 --- a/src/app/ui/collection-tools/collection-tools.component.ts +++ b/src/app/ui/collection-tools/collection-tools.component.ts @@ -69,6 +69,18 @@ export class CollectionToolsComponent implements OnInit { mySwiper:any //轮播图实例 gallery//viewerJs实例 + + rightIsShow = true; // 右侧楼层是否展示 + // 打开 右侧楼层 + openRight() { + this.rightIsShow = true; + } + + // 关闭 右侧楼层 + closeRight() { + console.log(123) + this.rightIsShow = false; + } //设置属性框 setAssetsProperty(obj){ //初始化viewerJs实例 @@ -174,12 +186,23 @@ export class CollectionToolsComponent implements OnInit { //节点详情 details(){ this.detailsAndattentBtn = true + console.log(this.canvasData.selectPanelPointBaseData) + } //注意事项 attent(){ this.detailsAndattentBtn = false + console.log(this.canvasData.selectPanelPointBaseData) + } + bottomIsShow = true//底部隐藏按钮 + //关闭底部 + closedbottom(){ + this.bottomIsShow = false + } + //打开底部 + openedbottom(){ + this.bottomIsShow = true } - //消防要素div边框高度调节 firecategoriesDivMouseDown(e){ document.onmousemove = (ev) => { diff --git a/src/app/ui/dangerous/dangerous.component.html b/src/app/ui/dangerous/dangerous.component.html index 3a49d5b..829b567 100644 --- a/src/app/ui/dangerous/dangerous.component.html +++ b/src/app/ui/dangerous/dangerous.component.html @@ -1,7 +1,28 @@
-
-
危化品类型
-
危化品分布
+
+
危化品类型
+
危化品分布
+
+ volume_up +
+
+
泵房
+
控制室
+ +
+
+
+ settings_voice +
+
+ 按住说话 +
+
+ search +
+
+
+
diff --git a/src/app/ui/dangerous/dangerous.component.scss b/src/app/ui/dangerous/dangerous.component.scss index 150b9c7..35e823d 100644 --- a/src/app/ui/dangerous/dangerous.component.scss +++ b/src/app/ui/dangerous/dangerous.component.scss @@ -9,7 +9,7 @@ width: 100%; padding-top: 10px; font-size: 20px; - div{ + .divtype{ display: inline-block; width: 126px; height: 35px; @@ -22,6 +22,73 @@ .selectedBtn{ background-color: #e88108; } + .bigTalkBox{ + user-select: none; + .titleIcon{ + font-size: 33px; + vertical-align: sub; + color: white; + cursor: pointer; + } + .talkBox{ + width: 309px; + height: 326px; + border: 1px solid #30bbec; + background-color: #013a64; + opacity: .9 ; + position: absolute; + top: 32px; + right:4px; + z-index: 2000; + .btndiv{ + div{ + border-radius: 18px; + width: 70px; + height: 30px; + text-align: center; + line-height: 30px; + display: inline-block; + font-size: 13px; + color: white; + cursor: pointer; + + } + div:nth-child(1){ + background-color: #fe9400; + margin: 10px; + } + div:nth-child(2){ + background-color: #f95e5a; + } + } + .bottomDiv{ + position: absolute; + bottom:6px; + width: 100%; + height: 32px; + line-height: 32px; + display: flex; + color: white; + text-align: center; + mat-icon{ + vertical-align: sub; + } + div:nth-child(1){ + flex: 1; + } + div:nth-child(2){ + flex: 6; + color: #409eff; + background: url('../../../assets/images/输入框.png'); + background-size: 100% 100%; + } + div:nth-child(3){ + flex: 1; + + } + } + } + } } .body{ width: 99.9%; @@ -190,3 +257,5 @@ top: 0; } + + diff --git a/src/app/ui/dangerous/dangerous.component.ts b/src/app/ui/dangerous/dangerous.component.ts index 3fe0e24..3cf7dbc 100644 --- a/src/app/ui/dangerous/dangerous.component.ts +++ b/src/app/ui/dangerous/dangerous.component.ts @@ -11,6 +11,11 @@ export class DangerousComponent implements OnInit { map:any //地图 ngOnInit(): void { + } + //打开说话框 + isOpenTalk = false + openTalkDiv(){ + this.isOpenTalk = !this.isOpenTalk } selectedIndex = 0 typedata = [ @@ -157,7 +162,10 @@ export class DangerousComponent implements OnInit { detailNode = null openDetails(item){ this.detailNode = item - this.isOpen = true + if(item.content){ + this.isOpen = true + } + this.num = 0 } diff --git a/src/app/ui/plan-assistance/plan-assistance.component.html b/src/app/ui/plan-assistance/plan-assistance.component.html index 8e9cf2c..d7a3c2e 100644 --- a/src/app/ui/plan-assistance/plan-assistance.component.html +++ b/src/app/ui/plan-assistance/plan-assistance.component.html @@ -1,6 +1,7 @@
+
-
到场力量
+
到场力量
@@ -11,7 +12,7 @@
已到场
@@ -68,8 +69,8 @@

-

{{canvasData.selectCar.LinkCar}}

-

{{canvasData.selectCar.WaterOccupy}}

+

{{canvasData.selectCar.LinkCar}}

+

{{canvasData.selectCar.WaterOccupy}}

diff --git a/src/app/ui/plan-assistance/plan-assistance.component.scss b/src/app/ui/plan-assistance/plan-assistance.component.scss index 397937a..78e6f57 100644 --- a/src/app/ui/plan-assistance/plan-assistance.component.scss +++ b/src/app/ui/plan-assistance/plan-assistance.component.scss @@ -77,6 +77,16 @@ } } } +//打开关闭左侧 车辆 +.openLeft { + width: 300px; + transition: width 0.5s; +} +.closeLeft { + width: 0px; + min-width: 0px; + transition: width 0.5s; +} //选中状态 .selectIcon { @@ -124,7 +134,16 @@ display: flex; align-items: center; justify-content: center; - p { flex: 1; text-align: center; line-height: 35px; } + p { + color: #fff; + flex: 1; + text-align: center; + line-height: 35px; + overflow: hidden; + text-overflow:ellipsis; + white-space: nowrap; + cursor: pointer; + } } .taskInput { width: 100px; diff --git a/src/app/ui/plan-assistance/plan-assistance.component.ts b/src/app/ui/plan-assistance/plan-assistance.component.ts index 4a7cf84..07b884c 100644 --- a/src/app/ui/plan-assistance/plan-assistance.component.ts +++ b/src/app/ui/plan-assistance/plan-assistance.component.ts @@ -6955,7 +6955,7 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }, Name: '水罐消防车', FireTeamName: '八塘消防救援站', // 所属消防队 - ReachTime: 240, // 到场剩余时间 + ReachTime: 237, // 到场剩余时间 WaterYield: '12t', // 载水量 Foam: '0t', // 载泡沫 PeopleNum: 6, // 载人数 @@ -7009,7 +7009,7 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }, Name: '水罐泡沫消防车', FireTeamName: '八塘消防救援站', // 所属消防队 - ReachTime: 240, // 到场剩余时间 + ReachTime: 249, // 到场剩余时间 WaterYield: '6t', // 载水量 Foam: '2t', // 载泡沫 PeopleNum: 6, // 载人数 @@ -7063,7 +7063,7 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }, Name: '水罐泡沫消防车', FireTeamName: '八塘消防救援站', // 所属消防队 - ReachTime: 240, // 到场剩余时间 + ReachTime: 277, // 到场剩余时间 WaterYield: '3t', // 载水量 Foam: '1t', // 载泡沫 PeopleNum: 8, // 载人数 @@ -7117,7 +7117,7 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }, Name: '举高喷射消防车', FireTeamName: '八塘消防救援站', // 所属消防队 - ReachTime: 300, // 到场剩余时间 + ReachTime: 310, // 到场剩余时间 WaterYield: '16t', // 载水量 Foam: '2t', // 载泡沫 PeopleNum: 4, // 载人数 @@ -7171,7 +7171,7 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }, Name: '水罐泡沫消防车', FireTeamName: '龚州消防救援站', // 所属消防队 - ReachTime: 660, // 到场剩余时间 + ReachTime: 666, // 到场剩余时间 WaterYield: '6t', // 载水量 Foam: '2t', // 载泡沫 PeopleNum: 6, // 载人数 @@ -7225,7 +7225,7 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }, Name: '水罐泡沫消防车', FireTeamName: '龚州消防救援站', // 所属消防队 - ReachTime: 720, // 到场剩余时间 + ReachTime: 721, // 到场剩余时间 WaterYield: '5t', // 载水量 Foam: '1t', // 载泡沫 PeopleNum: 6, // 载人数 @@ -7279,7 +7279,7 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }, Name: '水罐泡沫消防车', FireTeamName: '龚州消防救援站', // 所属消防队 - ReachTime: 960, // 到场剩余时间 + ReachTime: 978, // 到场剩余时间 WaterYield: '3t', // 载水量 Foam: '1t', // 载泡沫 PeopleNum: 6, // 载人数 @@ -7333,7 +7333,7 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }, Name: '举高喷射消防车', FireTeamName: '龚州消防救援站', // 所属消防队 - ReachTime: 960, // 到场剩余时间 + ReachTime: 999, // 到场剩余时间 WaterYield: '18t', // 载水量 Foam: '2t', // 载泡沫 PeopleNum: 4, // 载人数 @@ -7364,11 +7364,6 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { } ]; - bottomIsShow = false; // 底部车辆信息是否展示 - rightIsShow = true; // 右侧楼层是否展示 - rightSayIsShow = false; // 右侧语音是否展示 - selectCarID = ''; // 选中车辆 样式 - ngOnInit(): void { const that = this; window.setTimeout(() => { @@ -7387,8 +7382,12 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { this.workingArea.on('select', obj => { // 选中素材属性注入函数 if (obj && obj.assetData && obj.assetData.ReachTime != undefined) { + this.selectCarID = JSON.parse(JSON.stringify( obj.assetData.Id || '' )); //选中样式 赋值ID + let linkCar = this.canvasData.getLinkCarName(obj) //连接车辆 + let waterOccupy = this.canvasData.getWaterOccupyName(obj) //水源占用 + obj.assetData.LinkCar = linkCar //连接车辆 + obj.assetData.WaterOccupy = waterOccupy //水源占用 this.canvasData.selectCar = obj.assetData; - this.selectCarID = JSON.parse(JSON.stringify( obj.assetData.Id || '' )); this.bottomIsShow = true; } }); @@ -7399,6 +7398,11 @@ export class PlanAssistanceComponent implements OnInit, AfterViewInit { }); } + bottomIsShow:boolean = false; // 底部车辆信息是否展示 + rightIsShow:boolean = true; // 右侧楼层是否展示 + rightSayIsShow:boolean = false; // 右侧语音是否展示 + selectCarID:string = ''; // 选中车辆ID 选中效果css + // 开始绘制 plot(e) { e == 0 ? this.workingArea.beginPaintingArrows() : this.workingArea.beginPaintPipeline(); diff --git a/src/app/ui/plan/collection-tools.component.html b/src/app/ui/plan/collection-tools.component.html index 2fcbec8..83a7929 100644 --- a/src/app/ui/plan/collection-tools.component.html +++ b/src/app/ui/plan/collection-tools.component.html @@ -8,6 +8,7 @@
{{item.name}}
+
volume_up
@@ -29,6 +30,7 @@
+
diff --git a/src/app/ui/similar-plans/similar-plans.component.html b/src/app/ui/similar-plans/similar-plans.component.html index c396c6d..5483b3c 100644 --- a/src/app/ui/similar-plans/similar-plans.component.html +++ b/src/app/ui/similar-plans/similar-plans.component.html @@ -2,6 +2,28 @@
返回
+
+ volume_up +
+
+
泵房
+
控制室
+ +
+
+
+ settings_voice +
+
+ 按住说话 +
+
+ search +
+
+
+
+
diff --git a/src/app/ui/similar-plans/similar-plans.component.scss b/src/app/ui/similar-plans/similar-plans.component.scss index f829534..1586d5b 100644 --- a/src/app/ui/similar-plans/similar-plans.component.scss +++ b/src/app/ui/similar-plans/similar-plans.component.scss @@ -35,7 +35,7 @@ } .backBtn{ position: absolute; - right: 30px; + right: 60px; top: 8px; width: 80px; height: 30px; @@ -49,4 +49,74 @@ } .backBtn:hover{ background-color: #0c4c69; -} \ No newline at end of file +} +.bigTalkBox{ + user-select: none; + .titleIcon{ + font-size: 33px; + vertical-align: sub; + color: white; + cursor: pointer; + } + .talkBox{ + width: 309px; + height: 326px; + border: 1px solid #30bbec; + background-color: #013a64; + opacity: .9 ; + position: absolute; + top: 32px; + right:4px; + z-index: 2000; + .btndiv{ + div{ + border-radius: 18px; + width: 70px; + height: 30px; + text-align: center; + line-height: 30px; + display: inline-block; + font-size: 13px; + color: white; + cursor: pointer; + + } + div:nth-child(1){ + background-color: #fe9400; + margin: 10px; + } + div:nth-child(2){ + background-color: #f95e5a; + } + } + .bottomDiv{ + position: absolute; + bottom:6px; + width: 100%; + height: 32px; + line-height: 32px; + display: flex; + color: white; + text-align: center; + mat-icon{ + vertical-align: sub; + } + div:nth-child(1){ + flex: 1; + } + div:nth-child(2){ + flex: 6; + color: #409eff; + background: url('../../../assets/images/输入框.png'); + background-size: 100% 100%; + } + div:nth-child(3){ + flex: 1; + + } + } + } + } + .cssClass{ + top: -42px!important; + } \ No newline at end of file diff --git a/src/app/ui/similar-plans/similar-plans.component.ts b/src/app/ui/similar-plans/similar-plans.component.ts index 493e915..328c7aa 100644 --- a/src/app/ui/similar-plans/similar-plans.component.ts +++ b/src/app/ui/similar-plans/similar-plans.component.ts @@ -13,7 +13,11 @@ export class SimilarPlansComponent implements OnInit { ngOnInit(): void { } - + //打开说话框 + isOpenTalk = false + openTalkDiv(){ + this.isOpenTalk = !this.isOpenTalk + } leisiYuan=[ {danweiName:"广西钦州志诚化工有限公司",year:"XXXX年",zhoahuo:"XXX",weizhi:"2#储罐",xiangjin:parseFloat("80%")}, diff --git a/src/app/working-area/charm.js b/src/app/working-area/charm.js new file mode 100644 index 0000000..a87804d --- /dev/null +++ b/src/app/working-area/charm.js @@ -0,0 +1,836 @@ +export class Charm { + constructor(renderingEngine = PIXI) { + + if (renderingEngine === undefined) throw new Error("Please assign a rendering engine in the constructor before using charm.js"); + + //Find out which rendering engine is being used (the default is Pixi) + this.renderer = ""; + + //If the `renderingEngine` is Pixi, set up Pixi object aliases + if (renderingEngine.ParticleContainer && renderingEngine.Sprite) { + this.renderer = "pixi"; + } + + + //An array to store the global tweens + this.globalTweens = []; + + //An object that stores all the easing formulas + this.easingFormulas = { + + //Linear + linear(x) { + return x; + }, + + //Smoothstep + smoothstep(x) { + return x * x * (3 - 2 * x); + }, + smoothstepSquared(x) { + return Math.pow((x * x * (3 - 2 * x)), 2); + }, + smoothstepCubed(x) { + return Math.pow((x * x * (3 - 2 * x)), 3); + }, + + //Acceleration + acceleration(x) { + return x * x; + }, + accelerationCubed(x) { + return Math.pow(x * x, 3); + }, + + //Deceleration + deceleration(x) { + return 1 - Math.pow(1 - x, 2); + }, + decelerationCubed(x) { + return 1 - Math.pow(1 - x, 3); + }, + + //Sine + sine(x) { + return Math.sin(x * Math.PI / 2); + }, + sineSquared(x) { + return Math.pow(Math.sin(x * Math.PI / 2), 2); + }, + sineCubed(x) { + return Math.pow(Math.sin(x * Math.PI / 2), 2); + }, + inverseSine(x) { + return 1 - Math.sin((1 - x) * Math.PI / 2); + }, + inverseSineSquared(x) { + return 1 - Math.pow(Math.sin((1 - x) * Math.PI / 2), 2); + }, + inverseSineCubed(x) { + return 1 - Math.pow(Math.sin((1 - x) * Math.PI / 2), 3); + }, + + //Spline + spline(t, p0, p1, p2, p3) { + return 0.5 * ( + (2 * p1) + + (-p0 + p2) * t + + (2 * p0 - 5 * p1 + 4 * p2 - p3) * t * t + + (-p0 + 3 * p1 - 3 * p2 + p3) * t * t * t + ); + }, + + //Bezier curve + cubicBezier(t, a, b, c, d) { + let t2 = t * t; + let t3 = t2 * t; + return a + (-a * 3 + t * (3 * a - a * t)) * t + (3 * b + t * (-6 * b + b * 3 * t)) * t + (c * 3 - c * 3 * t) * t2 + d * t3; + } + }; + + //Add `scaleX` and `scaleY` properties to Pixi sprites + this._addScaleProperties = (sprite) => { + if (this.renderer === "pixi") { + if (!("scaleX" in sprite) && ("scale" in sprite) && ("x" in sprite.scale)) { + Object.defineProperty( + sprite, + "scaleX", { + get() { + return sprite.scale.x + }, + set(value) { + sprite.scale.x = value + } + } + ); + } + if (!("scaleY" in sprite) && ("scale" in sprite) && ("y" in sprite.scale)) { + Object.defineProperty( + sprite, + "scaleY", { + get() { + return sprite.scale.y + }, + set(value) { + sprite.scale.y = value + } + } + ); + } + } + }; + } + + //The low level `tweenProperty` function is used as the foundation + //for the the higher level tween methods. + tweenProperty( + sprite, //Sprite object + property, //String property + startValue, //Tween start value + endValue, //Tween end value + totalFrames, //Duration in frames + type = "smoothstep", //The easing type + yoyo = false, //Yoyo? + delayBeforeRepeat = 0 //Delay in frames before repeating + ) { + + //Create the tween object + let o = {}; + + //If the tween is a bounce type (a spline), set the + //start and end magnitude values + let typeArray = type.split(" "); + if (typeArray[0] === "bounce") { + o.startMagnitude = parseInt(typeArray[1]); + o.endMagnitude = parseInt(typeArray[2]); + } + + //Use `o.start` to make a new tween using the current + //end point values + o.start = (startValue, endValue) => { + + //Clone the start and end values so that any possible references to sprite + //properties are converted to ordinary numbers + o.startValue = JSON.parse(JSON.stringify(startValue)); + o.endValue = JSON.parse(JSON.stringify(endValue)); + o.playing = true; + o.totalFrames = totalFrames; + o.frameCounter = 0; + + //Add the tween to the global `tweens` array. The `tweens` array is + //updated on each frame + this.globalTweens.push(o); + }; + + //Call `o.start` to start the tween + o.start(startValue, endValue); + + //The `update` method will be called on each frame by the game loop. + //This is what makes the tween move + o.update = () => { + + let time, curvedTime; + + if (o.playing) { + + //If the elapsed frames are less than the total frames, + //use the tweening formulas to move the sprite + if (o.frameCounter < o.totalFrames) { + + //Find the normalized value + let normalizedTime = o.frameCounter / o.totalFrames; + + //Select the correct easing function from the + //`ease` object’s library of easing functions + + + //If it's not a spline, use one of the ordinary easing functions + if (typeArray[0] !== "bounce") { + curvedTime = this.easingFormulas[type](normalizedTime); + } + + //If it's a spline, use the `spline` function and apply the + //2 additional `type` array values as the spline's start and + //end points + else { + curvedTime = this.easingFormulas.spline(normalizedTime, o.startMagnitude, 0, 1, o.endMagnitude); + } + + //Interpolate the sprite's property based on the curve + sprite[property] = (o.endValue * curvedTime) + (o.startValue * (1 - curvedTime)); + + o.frameCounter += 1; + } + + //When the tween has finished playing, run the end tasks + else { + sprite[property] = o.endValue; + o.end(); + } + } + }; + + //The `end` method will be called when the tween is finished + o.end = () => { + + //Set `playing` to `false` + o.playing = false; + + //Call the tween's `onComplete` method, if it's been assigned + if (o.onComplete) o.onComplete(); + + //Remove the tween from the `tweens` array + this.globalTweens.splice(this.globalTweens.indexOf(o), 1); + + //If the tween's `yoyo` property is `true`, create a new tween + //using the same values, but use the current tween's `startValue` + //as the next tween's `endValue` + if (yoyo) { + this.wait(delayBeforeRepeat).then(() => { + o.start(o.endValue, o.startValue); + }); + } + }; + + //Pause and play methods + o.play = () => o.playing = true; + o.pause = () => o.playing = false; + + //Return the tween object + return o; + } + + //`makeTween` is a general low-level method for making complex tweens + //out of multiple `tweenProperty` functions. Its one argument, + //`tweensToAdd` is an array containing multiple `tweenProperty` calls + + makeTween(tweensToAdd) { + + //Create an object to manage the tweens + let o = {}; + + //Create a `tweens` array to store the new tweens + o.tweens = []; + + //Make a new tween for each array + tweensToAdd.forEach(tweenPropertyArguments => { + + //Use the tween property arguments to make a new tween + let newTween = this.tweenProperty(...tweenPropertyArguments); + + //Push the new tween into this object's internal `tweens` array + o.tweens.push(newTween); + }); + + //Add a counter to keep track of the + //number of tweens that have completed their actions + let completionCounter = 0; + + //`o.completed` will be called each time one of the tweens + //finishes + o.completed = () => { + + //Add 1 to the `completionCounter` + completionCounter += 1; + + //If all tweens have finished, call the user-defined `onComplete` + //method, if it's been assigned. Reset the `completionCounter` + if (completionCounter === o.tweens.length) { + if (o.onComplete) o.onComplete(); + completionCounter = 0; + } + }; + + //Add `onComplete` methods to all tweens + o.tweens.forEach(tween => { + tween.onComplete = () => o.completed(); + }); + + //Add pause and play methods to control all the tweens + o.pause = () => { + o.tweens.forEach(tween => { + tween.playing = false; + }); + }; + o.play = () => { + o.tweens.forEach(tween => { + tween.playing = true; + }); + }; + + //Return the tween object + return o; + } + + /* High level tween methods */ + + //1. Simple tweens + + //`fadeOut` + fadeOut(sprite, frames = 60) { + return this.tweenProperty( + sprite, "alpha", sprite.alpha, 0, frames, "sine" + ); + } + + //`fadeIn` + fadeIn(sprite, frames = 60) { + return this.tweenProperty( + sprite, "alpha", sprite.alpha, 1, frames, "sine" + ); + } + + //`pulse` + //Fades the sprite in and out at a steady rate. + //Set the `minAlpha` to something greater than 0 if you + //don't want the sprite to fade away completely + pulse(sprite, frames = 60, minAlpha = 0) { + return this.tweenProperty( + sprite, "alpha", sprite.alpha, minAlpha, frames, "smoothstep", true + ); + } + + //2. Complex tweens + + slide( + sprite, endX, endY, + frames = 60, type = "smoothstep", yoyo = false, delayBeforeRepeat = 0 + ) { + return this.makeTween([ + + //Create the x axis tween + [sprite, "x", sprite.x, endX, frames, type, yoyo, delayBeforeRepeat], + + //Create the y axis tween + [sprite, "y", sprite.y, endY, frames, type, yoyo, delayBeforeRepeat] + + ]); + } + + breathe( + sprite, endScaleX = 0.8, endScaleY = 0.8, + frames = 60, yoyo = true, delayBeforeRepeat = 0 + ) { + + //Add `scaleX` and `scaleY` properties to Pixi sprites + this._addScaleProperties(sprite); + + return this.makeTween([ + + //Create the scaleX tween + [ + sprite, "scaleX", sprite.scaleX, endScaleX, + frames, "smoothstepSquared", yoyo, delayBeforeRepeat + ], + + //Create the scaleY tween + [ + sprite, "scaleY", sprite.scaleY, endScaleY, + frames, "smoothstepSquared", yoyo, delayBeforeRepeat + ] + ]); + } + + scale(sprite, endScaleX = 0.5, endScaleY = 0.5, frames = 60) { + + //Add `scaleX` and `scaleY` properties to Pixi sprites + this._addScaleProperties(sprite); + + return this.makeTween([ + + //Create the scaleX tween + [ + sprite, "scaleX", sprite.scaleX, endScaleX, + frames, "smoothstep", false + ], + + //Create the scaleY tween + [ + sprite, "scaleY", sprite.scaleY, endScaleY, + frames, "smoothstep", false + ] + ]); + } + + strobe( + sprite, scaleFactor = 1.3, startMagnitude = 10, endMagnitude = 20, + frames = 10, yoyo = true, delayBeforeRepeat = 0 + ) { + + let bounce = "bounce " + startMagnitude + " " + endMagnitude; + + //Add `scaleX` and `scaleY` properties to Pixi sprites + this._addScaleProperties(sprite); + + return this.makeTween([ + + //Create the scaleX tween + [ + sprite, "scaleX", sprite.scaleX, scaleFactor, frames, + bounce, yoyo, delayBeforeRepeat + ], + + //Create the scaleY tween + [ + sprite, "scaleY", sprite.scaleY, scaleFactor, frames, + bounce, yoyo, delayBeforeRepeat + ] + ]); + } + + wobble( + sprite, + scaleFactorX = 1.2, + scaleFactorY = 1.2, + frames = 10, + xStartMagnitude = 10, + xEndMagnitude = 10, + yStartMagnitude = -10, + yEndMagnitude = -10, + friction = 0.98, + yoyo = true, + delayBeforeRepeat = 0 + ) { + + let bounceX = "bounce " + xStartMagnitude + " " + xEndMagnitude; + let bounceY = "bounce " + yStartMagnitude + " " + yEndMagnitude; + + //Add `scaleX` and `scaleY` properties to Pixi sprites + this._addScaleProperties(sprite); + + let o = this.makeTween([ + + //Create the scaleX tween + [ + sprite, "scaleX", sprite.scaleX, scaleFactorX, frames, + bounceX, yoyo, delayBeforeRepeat + ], + + //Create the scaleY tween + [ + sprite, "scaleY", sprite.scaleY, scaleFactorY, frames, + bounceY, yoyo, delayBeforeRepeat + ] + ]); + + //Add some friction to the `endValue` at the end of each tween + o.tweens.forEach(tween => { + tween.onComplete = () => { + + //Add friction if the `endValue` is greater than 1 + if (tween.endValue > 1) { + tween.endValue *= friction; + + //Set the `endValue` to 1 when the effect is finished and + //remove the tween from the global `tweens` array + if (tween.endValue <= 1) { + tween.endValue = 1; + this.removeTween(tween); + } + } + }; + }); + + return o; + } + + //3. Motion path tweens + + followCurve( + sprite, + pointsArray, + totalFrames, + type = "smoothstep", + yoyo = false, + delayBeforeRepeat = 0 + ) { + + //Create the tween object + let o = {}; + + //If the tween is a bounce type (a spline), set the + //start and end magnitude values + let typeArray = type.split(" "); + if (typeArray[0] === "bounce") { + o.startMagnitude = parseInt(typeArray[1]); + o.endMagnitude = parseInt(typeArray[2]); + } + + //Use `tween.start` to make a new tween using the current + //end point values + o.start = (pointsArray) => { + o.playing = true; + o.totalFrames = totalFrames; + o.frameCounter = 0; + + //Clone the points array + o.pointsArray = JSON.parse(JSON.stringify(pointsArray)); + + //Add the tween to the `globalTweens` array. The `globalTweens` array is + //updated on each frame + this.globalTweens.push(o); + }; + + //Call `tween.start` to start the first tween + o.start(pointsArray); + + //The `update` method will be called on each frame by the game loop. + //This is what makes the tween move + o.update = () => { + + let normalizedTime, curvedTime, + p = o.pointsArray; + + if (o.playing) { + + //If the elapsed frames are less than the total frames, + //use the tweening formulas to move the sprite + if (o.frameCounter < o.totalFrames) { + + //Find the normalized value + normalizedTime = o.frameCounter / o.totalFrames; + + //Select the correct easing function + + //If it's not a spline, use one of the ordinary tween + //functions + if (typeArray[0] !== "bounce") { + curvedTime = this.easingFormulas[type](normalizedTime); + } + + //If it's a spline, use the `spline` function and apply the + //2 additional `type` array values as the spline's start and + //end points + else { + //curve = tweenFunction.spline(n, type[1], 0, 1, type[2]); + curvedTime = this.easingFormulas.spline(normalizedTime, o.startMagnitude, 0, 1, o.endMagnitude); + } + + //Apply the Bezier curve to the sprite's position + sprite.x = this.easingFormulas.cubicBezier(curvedTime, p[0][0], p[1][0], p[2][0], p[3][0]); + sprite.y = this.easingFormulas.cubicBezier(curvedTime, p[0][1], p[1][1], p[2][1], p[3][1]); + + //Add one to the `elapsedFrames` + o.frameCounter += 1; + } + + //When the tween has finished playing, run the end tasks + else { + //sprite[property] = o.endValue; + o.end(); + } + } + }; + + //The `end` method will be called when the tween is finished + o.end = () => { + + //Set `playing` to `false` + o.playing = false; + + //Call the tween's `onComplete` method, if it's been + //assigned + if (o.onComplete) o.onComplete(); + + //Remove the tween from the global `tweens` array + this.globalTweens.splice(this.globalTweens.indexOf(o), 1); + + //If the tween's `yoyo` property is `true`, reverse the array and + //use it to create a new tween + if (yoyo) { + this.wait(delayBeforeRepeat).then(() => { + o.pointsArray = o.pointsArray.reverse(); + o.start(o.pointsArray); + }); + } + }; + + //Pause and play methods + o.pause = () => { + o.playing = false; + }; + o.play = () => { + o.playing = true; + }; + + //Return the tween object + return o; + } + + walkPath( + sprite, //The sprite + originalPathArray, //A 2D array of waypoints + totalFrames = 300, //The duration, in frames + type = "smoothstep", //The easing type + loop = false, //Should the animation loop? + yoyo = false, //Shoud the direction reverse? + delayBetweenSections = 0 //Delay, in milliseconds, between sections + ) { + + //Clone the path array so that any possible references to sprite + //properties are converted into ordinary numbers + let pathArray = JSON.parse(JSON.stringify(originalPathArray)); + + //Figure out the duration, in frames, of each path section by + //dividing the `totalFrames` by the length of the `pathArray` + let frames = totalFrames / pathArray.length; + + //Set the current point to 0, which will be the first waypoint + let currentPoint = 0; + + //The `makePath` function creates a single tween between two points and + //then schedules the next path to be made after it + let makePath = (currentPoint) => { + + //Use the `makeTween` function to tween the sprite's + //x and y position + let tween = this.makeTween([ + + //Create the x axis tween between the first x value in the + //current point and the x value in the following point + [ + sprite, + "x", + pathArray[currentPoint][0], + pathArray[currentPoint + 1][0], + frames, + type + ], + + //Create the y axis tween in the same way + [ + sprite, + "y", + pathArray[currentPoint][1], + pathArray[currentPoint + 1][1], + frames, + type + ] + ]); + + //When the tween is complete, advance the `currentPoint` by one. + //Add an optional delay between path segments, and then make the + //next connecting path + tween.onComplete = () => { + + //Advance to the next point + currentPoint += 1; + + //If the sprite hasn't reached the end of the + //path, tween the sprite to the next point + if (currentPoint < pathArray.length - 1) { + this.wait(delayBetweenSections).then(() => { + tween = makePath(currentPoint); + }); + } + + //If we've reached the end of the path, optionally + //loop and yoyo it + else { + + //Reverse the path if `loop` is `true` + if (loop) { + + //Reverse the array if `yoyo` is `true` + if (yoyo) pathArray.reverse(); + + //Optionally wait before restarting + this.wait(delayBetweenSections).then(() => { + + //Reset the `currentPoint` to 0 so that we can + //restart at the first point + currentPoint = 0; + + //Set the sprite to the first point + sprite.x = pathArray[0][0]; + sprite.y = pathArray[0][1]; + + //Make the first new path + tween = makePath(currentPoint); + + //... and so it continues! + }); + } + } + }; + + //Return the path tween to the main function + return tween; + }; + + //Make the first path using the internal `makePath` function (below) + let tween = makePath(currentPoint); + + //Pass the tween back to the main program + return tween; + } + + walkCurve( + sprite, //The sprite + pathArray, //2D array of Bezier curves + totalFrames = 300, //The duration, in frames + type = "smoothstep", //The easing type + loop = false, //Should the animation loop? + yoyo = false, //Should the direction reverse? + delayBeforeContinue = 0 //Delay, in milliseconds, between sections + ) { + + //Divide the `totalFrames` into sections for each part of the path + let frames = totalFrames / pathArray.length; + + //Set the current curve to 0, which will be the first one + let currentCurve = 0; + + //The `makePath` function + let makePath = (currentCurve) => { + + //Use the custom `followCurve` function to make + //a sprite follow a curve + let tween = this.followCurve( + sprite, + pathArray[currentCurve], + frames, + type + ); + + //When the tween is complete, advance the `currentCurve` by one. + //Add an optional delay between path segments, and then make the + //next path + tween.onComplete = () => { + currentCurve += 1; + if (currentCurve < pathArray.length) { + this.wait(delayBeforeContinue).then(() => { + tween = makePath(currentCurve); + }); + } + + //If we've reached the end of the path, optionally + //loop and reverse it + else { + if (loop) { + if (yoyo) { + + //Reverse order of the curves in the `pathArray` + pathArray.reverse(); + + //Reverse the order of the points in each curve + pathArray.forEach(curveArray => curveArray.reverse()); + } + + //After an optional delay, reset the sprite to the + //beginning of the path and make the next new path + this.wait(delayBeforeContinue).then(() => { + currentCurve = 0; + sprite.x = pathArray[0][0]; + sprite.y = pathArray[0][1]; + tween = makePath(currentCurve); + }); + } + } + }; + + //Return the path tween to the main function + return tween; + }; + + //Make the first path + let tween = makePath(currentCurve); + + //Pass the tween back to the main program + return tween; + } + + //4. Utilities + + /* + The `wait` method lets you set up a timed sequence of events + + wait(1000) + .then(() => console.log("One")) + .then(() => wait(1000)) + .then(() => console.log("Two")) + .then(() => wait(1000)) + .then(() => console.log("Three")) + + */ + + wait(duration = 0) { + return new Promise((resolve, reject) => { + setTimeout(resolve, duration); + }); + } + + //A utility to remove tweens from the game + removeTween(tweenObject) { + + //Remove the tween if `tweenObject` doesn't have any nested + //tween objects + if (!tweenObject.tweens) { + tweenObject.pause(); + + //array.splice(-1,1) will always remove last elemnt of array, so this + //extra check prevents that (Thank you, MCumic10! https://github.com/kittykatattack/charm/issues/5) + if (this.globalTweens.indexOf(tweenObject) != -1) { + this.globalTweens.splice(this.globalTweens.indexOf(tweenObject), 1); + } + + //Otherwise, remove the nested tween objects + } else { + tweenObject.pause(); + tweenObject.tweens.forEach(element => { + this.globalTweens.splice(this.globalTweens.indexOf(element), 1); + }); + } + } + + update() { + + //Update all the tween objects in the `globalTweens` array + if (this.globalTweens.length > 0) { + for (let i = this.globalTweens.length - 1; i >= 0; i--) { + let tween = this.globalTweens[i]; + if (tween) tween.update(); + } + } + } +} \ 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 75af60f..61dbf35 100644 --- a/src/app/working-area/working-area.component.ts +++ b/src/app/working-area/working-area.component.ts @@ -8,6 +8,7 @@ import {CacheTokenService} from '../http-interceptors/cache-token.service'; // import * as ObjectID from 'bson-objectid'; import { Router } from '@angular/router'; import { isThisSecond } from 'date-fns'; +import { Charm } from './charm'; @Component({ @@ -117,6 +118,10 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV */ public allowEdit = false; + public c; + public animation; + public animationIcon; + public animationTime; // 根据ID 找到数据 // 是否登录 @@ -227,6 +232,26 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV } this.emit('backgroundScale', this.backgroundImage.scale.x); } + /** + * + * @param icon 移动到选中车辆到屏幕中心点 + */ + public moveIconToScreenCenter(icon) { + if (icon.parent === this.backgroundImage && icon.assetData.Type === 1) { + 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.c.breathe(icon, 10, 10, 30, true, 0); + this.animationIcon = icon; + this.animationTime = setTimeout(() => { + this.animation?.pause(); + this.animationIcon?.scale.set(1); + }, 5000); + } + } /** * 创建画布 */ @@ -243,7 +268,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV const url = this.router.url; // tslint:disable-next-line: no-unused-expression url === this.verificationURL || url === this.verificationURLTwo ? this.isLogin() : null; - + this.c = new Charm(PIXI); this.createBackgroundImage(); // this.createPreviewSinglePointIcon(); // this.createPreviewLineSegment(); @@ -251,6 +276,7 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV // this.createEnterPaintEndButton(); // this.backgroundImage.addChild(this.paintingLine); this.on('select', obj => { + this.moveIconToScreenCenter(obj); if (this.allowEdit) { if (obj instanceof MultipointIcon) { obj.setPointVisiable(true); @@ -297,6 +323,8 @@ export class WorkingAreaComponent extends EventEmitter implements OnInit, AfterV }); this.app.ticker.add((delta) => { + this.c.update(); + this.mousePosition = this.app.renderer.plugins.interaction.mouse.global; this.previewSinglePointIcon.position = this.backgroundImage.toLocal(this.mousePosition);