From b451f4fa3e9b0f8cf8fe59771587dc2b4cf0578e Mon Sep 17 00:00:00 2001 From: joylink_fanyuhong <18706759286@163.com> Date: Thu, 17 Oct 2024 17:52:02 +0800 Subject: [PATCH] =?UTF-8?q?FAS=E6=96=B0=E5=A2=9E=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/drawIcon.svg | 9 +- .../FAS/ManualAlarmButtonInteraction.ts | 44 ++++++ .../graphics/FAS/SmokeDetectorInteraction.ts | 44 ++++++ src/drawApp/iscsApp.ts | 38 +++++ .../FAS/fasAlarm/FasAlarmAssistant.ts | 7 +- .../manualAlarmButton/ManualAlarmButton.json | 21 +++ .../manualAlarmButton/ManualAlarmButton.png | Bin 0 -> 4061 bytes .../manualAlarmButton/ManualAlarmButton.ts | 66 +++++++++ .../ManualAlarmButtonAssistant.ts | 131 ++++++++++++++++++ .../FAS/smokeDetector/SmokeDetector.json | 21 +++ .../FAS/smokeDetector/SmokeDetector.png | Bin 0 -> 650 bytes .../FAS/smokeDetector/SmokeDetector.ts | 63 +++++++++ .../smokeDetector/SmokeDetectorAssistant.ts | 123 ++++++++++++++++ src/layouts/IscsDrawLayout.vue | 4 + 14 files changed, 564 insertions(+), 7 deletions(-) create mode 100644 src/drawApp/graphics/FAS/ManualAlarmButtonInteraction.ts create mode 100644 src/drawApp/graphics/FAS/SmokeDetectorInteraction.ts create mode 100644 src/graphics/FAS/manualAlarmButton/ManualAlarmButton.json create mode 100644 src/graphics/FAS/manualAlarmButton/ManualAlarmButton.png create mode 100644 src/graphics/FAS/manualAlarmButton/ManualAlarmButton.ts create mode 100644 src/graphics/FAS/manualAlarmButton/ManualAlarmButtonAssistant.ts create mode 100644 src/graphics/FAS/smokeDetector/SmokeDetector.json create mode 100644 src/graphics/FAS/smokeDetector/SmokeDetector.png create mode 100644 src/graphics/FAS/smokeDetector/SmokeDetector.ts create mode 100644 src/graphics/FAS/smokeDetector/SmokeDetectorAssistant.ts diff --git a/public/drawIcon.svg b/public/drawIcon.svg index 575f9fd..3a336c1 100644 --- a/public/drawIcon.svg +++ b/public/drawIcon.svg @@ -102,5 +102,12 @@ - + + + + + + + + diff --git a/src/drawApp/graphics/FAS/ManualAlarmButtonInteraction.ts b/src/drawApp/graphics/FAS/ManualAlarmButtonInteraction.ts new file mode 100644 index 0000000..470a069 --- /dev/null +++ b/src/drawApp/graphics/FAS/ManualAlarmButtonInteraction.ts @@ -0,0 +1,44 @@ +import * as pb_1 from 'google-protobuf'; +import { GraphicDataBase } from '../GraphicDataBase'; +import { + ManualAlarmButton, + IManualAlarmButtonData, +} from 'src/graphics/FAS/manualAlarmButton/ManualAlarmButton'; +import { iscsGraphicData } from 'src/protos/iscs_graphic_data'; + +export class ManualAlarmButtonData + extends GraphicDataBase + implements IManualAlarmButtonData +{ + constructor(data?: iscsGraphicData.ManualAlarmButton) { + let cctvButton; + if (data) { + cctvButton = data; + } else { + cctvButton = new iscsGraphicData.ManualAlarmButton({ + common: GraphicDataBase.defaultCommonInfo(ManualAlarmButton.Type), + }); + } + super(cctvButton); + } + + public get data(): iscsGraphicData.ManualAlarmButton { + return this.getData(); + } + + get code(): string { + return this.data.code; + } + set code(v: string) { + this.data.code = v; + } + clone(): ManualAlarmButtonData { + return new ManualAlarmButtonData(this.data.cloneMessage()); + } + copyFrom(data: ManualAlarmButtonData): void { + pb_1.Message.copyInto(data.data, this.data); + } + eq(other: ManualAlarmButtonData): boolean { + return pb_1.Message.equals(this.data, other.data); + } +} diff --git a/src/drawApp/graphics/FAS/SmokeDetectorInteraction.ts b/src/drawApp/graphics/FAS/SmokeDetectorInteraction.ts new file mode 100644 index 0000000..0deb9e8 --- /dev/null +++ b/src/drawApp/graphics/FAS/SmokeDetectorInteraction.ts @@ -0,0 +1,44 @@ +import * as pb_1 from 'google-protobuf'; +import { GraphicDataBase } from '../GraphicDataBase'; +import { + SmokeDetector, + ISmokeDetectorData, +} from 'src/graphics/FAS/smokeDetector/SmokeDetector'; +import { iscsGraphicData } from 'src/protos/iscs_graphic_data'; + +export class SmokeDetectorData + extends GraphicDataBase + implements ISmokeDetectorData +{ + constructor(data?: iscsGraphicData.SmokeDetector) { + let cctvButton; + if (data) { + cctvButton = data; + } else { + cctvButton = new iscsGraphicData.SmokeDetector({ + common: GraphicDataBase.defaultCommonInfo(SmokeDetector.Type), + }); + } + super(cctvButton); + } + + public get data(): iscsGraphicData.SmokeDetector { + return this.getData(); + } + + get code(): string { + return this.data.code; + } + set code(v: string) { + this.data.code = v; + } + clone(): SmokeDetectorData { + return new SmokeDetectorData(this.data.cloneMessage()); + } + copyFrom(data: SmokeDetectorData): void { + pb_1.Message.copyInto(data.data, this.data); + } + eq(other: SmokeDetectorData): boolean { + return pb_1.Message.equals(this.data, other.data); + } +} diff --git a/src/drawApp/iscsApp.ts b/src/drawApp/iscsApp.ts index 1a4df6d..388ebbb 100644 --- a/src/drawApp/iscsApp.ts +++ b/src/drawApp/iscsApp.ts @@ -35,6 +35,18 @@ import { FasFailureControlHostDraw } from 'src/graphics/FAS/fireFailureControlHo import { FasAlarm, FasAlarmTemplate } from 'src/graphics/FAS/fasAlarm/FasAlarm'; import { FasAlarmData } from './graphics/FAS/FasAlarmInteraction'; import { FasAlarmDraw } from 'src/graphics/FAS/fasAlarm/FasAlarmAssistant'; +import { + ManualAlarmButton, + ManualAlarmButtonTemplate, +} from 'src/graphics/FAS/manualAlarmButton/ManualAlarmButton'; +import { ManualAlarmButtonData } from './graphics/FAS/ManualAlarmButtonInteraction'; +import { ManualAlarmButtonDraw } from 'src/graphics/FAS/manualAlarmButton/ManualAlarmButtonAssistant'; +import { + SmokeDetector, + SmokeDetectorTemplate, +} from 'src/graphics/FAS/smokeDetector/SmokeDetector'; +import { SmokeDetectorData } from './graphics/FAS/SmokeDetectorInteraction'; +import { SmokeDetectorDraw } from 'src/graphics/FAS/smokeDetector/SmokeDetectorAssistant'; // import { getOnlyToken } from 'src/configs/TokenManage'; let drawApp: IDrawApp | null = null; @@ -74,6 +86,14 @@ export function initIscsDrawApp(): IDrawApp { new FasFailureControlHostTemplate(new FasFailureControlHostData()) ); new FasAlarmDraw(app, new FasAlarmTemplate(new FasAlarmData())); + new ManualAlarmButtonDraw( + app, + new ManualAlarmButtonTemplate(new ManualAlarmButtonData()) + ); + new SmokeDetectorDraw( + app, + new SmokeDetectorTemplate(new SmokeDetectorData()) + ); app.addKeyboardListener( new KeyListener({ @@ -242,6 +262,14 @@ export async function loadDrawDatas(): Promise { fasOfPlatformAlarm.fasAlarms.forEach((fasAlarm) => { datas.push(new FasAlarmData(fasAlarm)); }); + fasOfPlatformAlarm.manualAlarmButtons.forEach( + (manualAlarmButton) => { + datas.push(new ManualAlarmButtonData(manualAlarmButton)); + } + ); + fasOfPlatformAlarm.smokeDetectors.forEach((smokeDetector) => { + datas.push(new SmokeDetectorData(smokeDetector)); + }); break; } } @@ -332,6 +360,16 @@ export function saveDrawDatas(app: IDrawApp) { } else if (g instanceof FasAlarm) { const fasAlarmData = g.saveData(); fasStorage.fasAlarms.push((fasAlarmData as FasAlarmData).data); + } else if (g instanceof ManualAlarmButton) { + const manualAlarmButtonData = g.saveData(); + fasStorage.manualAlarmButtons.push( + (manualAlarmButtonData as ManualAlarmButtonData).data + ); + } else if (g instanceof SmokeDetector) { + const smokeDetectorData = g.saveData(); + fasStorage.smokeDetectors.push( + (smokeDetectorData as SmokeDetectorData).data + ); } }); storage.fasOfPlatformAlarmStorages[i] = fasStorage; diff --git a/src/graphics/FAS/fasAlarm/FasAlarmAssistant.ts b/src/graphics/FAS/fasAlarm/FasAlarmAssistant.ts index 285850e..c74259a 100644 --- a/src/graphics/FAS/fasAlarm/FasAlarmAssistant.ts +++ b/src/graphics/FAS/fasAlarm/FasAlarmAssistant.ts @@ -16,12 +16,7 @@ export class FasAlarmDraw extends GraphicDrawAssistant< > { _fasAlarm: FasAlarm | null = null; constructor(app: IDrawApp, template: FasAlarmTemplate) { - super( - app, - template, - 'svguse:../drawIcon.svg#icon-fas-alarm', - '火灾故障控制主机' - ); + super(app, template, 'svguse:../drawIcon.svg#icon-fas-alarm', '警铃'); FasAlarmInteraction.init(app); } diff --git a/src/graphics/FAS/manualAlarmButton/ManualAlarmButton.json b/src/graphics/FAS/manualAlarmButton/ManualAlarmButton.json new file mode 100644 index 0000000..8225724 --- /dev/null +++ b/src/graphics/FAS/manualAlarmButton/ManualAlarmButton.json @@ -0,0 +1,21 @@ +{ + "frames": { + "normal.png": { + "frame": { "x": 0, "y": 0, "w": 26, "h": 24 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 26, "h": 24 }, + "sourceSize": { "w": 26, "h": 24 }, + "anchor": { "x": 0.5, "y": 0.5 } + } + }, + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "1.1", + "image": "ManualAlarmButton.png", + "format": "RGBA8888", + "size": { "w": 32, "h": 53 }, + "scale": "1", + "smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$" + } +} diff --git a/src/graphics/FAS/manualAlarmButton/ManualAlarmButton.png b/src/graphics/FAS/manualAlarmButton/ManualAlarmButton.png new file mode 100644 index 0000000000000000000000000000000000000000..1450d1789f707cee700114e8963d7979c3088ca3 GIT binary patch literal 4061 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 + } + + doRepaint(): void {} +} + +export class ManualAlarmButtonTemplate extends JlGraphicTemplate { + manualAlarmButtonTextures?: ManualAlarmButtonTextures; + constructor(dataTemplate: IManualAlarmButtonData) { + super(ManualAlarmButton.Type, { dataTemplate }); + this.loadAssets(); + } + new(): ManualAlarmButton { + if (this.manualAlarmButtonTextures) { + const g = new ManualAlarmButton(this.manualAlarmButtonTextures); + g.loadData(this.datas); + return g; + } + throw new Error('资源未加载/加载失败'); + } + async loadAssets(): Promise { + const texture = await Assets.load(ManualAlarmButtonAssets); + const manualAlarmButtonSheet = new Spritesheet( + texture, + ManualAlarmButtonJson + ); + const result = await manualAlarmButtonSheet.parse(); + this.manualAlarmButtonTextures = { + normal: result['normal.png'], + }; + return this.manualAlarmButtonTextures as ManualAlarmButtonTextures; + } +} diff --git a/src/graphics/FAS/manualAlarmButton/ManualAlarmButtonAssistant.ts b/src/graphics/FAS/manualAlarmButton/ManualAlarmButtonAssistant.ts new file mode 100644 index 0000000..edf6d51 --- /dev/null +++ b/src/graphics/FAS/manualAlarmButton/ManualAlarmButtonAssistant.ts @@ -0,0 +1,131 @@ +import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js'; +import { + AbsorbableLine, + AbsorbablePosition, + GraphicDrawAssistant, + GraphicInteractionPlugin, + GraphicTransformEvent, + IDrawApp, + JlGraphic, +} from 'jl-graphic'; +import { + IManualAlarmButtonData, + ManualAlarmButton, + ManualAlarmButtonTemplate, +} from './ManualAlarmButton'; + +export class ManualAlarmButtonDraw extends GraphicDrawAssistant< + ManualAlarmButtonTemplate, + IManualAlarmButtonData +> { + _manualAlarmButton: ManualAlarmButton | null = null; + constructor(app: IDrawApp, template: ManualAlarmButtonTemplate) { + super( + app, + template, + 'svguse:../drawIcon.svg#icon-manual-alarm-button', + '手动火灾报警按钮' + ); + ManualAlarmButtonInteraction.init(app); + } + + bind(): void { + super.bind(); + if (!this._manualAlarmButton) { + this._manualAlarmButton = this.graphicTemplate.new(); + this.container.addChild(this._manualAlarmButton); + } + } + + public get manualAlarmButton(): ManualAlarmButton { + if (!this._manualAlarmButton) { + this._manualAlarmButton = this.graphicTemplate.new(); + this.container.addChild(this._manualAlarmButton); + } + return this._manualAlarmButton; + } + + redraw(cp: Point): void { + this.manualAlarmButton.position.copyFrom(cp); + } + onLeftUp(e: FederatedMouseEvent): void { + this.manualAlarmButton.position.copyFrom( + this.toCanvasCoordinates(e.global) + ); + this.createAndStore(true); + } + prepareData(data: IManualAlarmButtonData): boolean { + data.transform = this.manualAlarmButton.saveTransform(); + return true; + } + onEsc(): void { + this.finish(); + } +} + +/** + * 构建吸附线 + * @param manualAlarmButton + */ +function buildAbsorbablePositions( + manualAlarmButton: ManualAlarmButton +): AbsorbablePosition[] { + const aps: AbsorbablePosition[] = []; + const manualAlarmButtons = + manualAlarmButton.queryStore.queryByType( + ManualAlarmButton.Type + ); + const canvas = manualAlarmButton.getCanvas(); + manualAlarmButtons.forEach((item) => { + if (item.id === manualAlarmButton.id) { + return; + } + const ala = new AbsorbableLine( + new Point(item.x, 0), + new Point(item.x, canvas.height) + ); + const alb = new AbsorbableLine( + new Point(0, item.y), + new Point(canvas.width, item.y) + ); + aps.push(ala); + aps.push(alb); + }); + + return aps; +} + +export class ManualAlarmButtonInteraction extends GraphicInteractionPlugin { + static Name = 'manual_alarm_button_transform'; + constructor(app: IDrawApp) { + super(ManualAlarmButtonInteraction.Name, app); + } + static init(app: IDrawApp) { + return new ManualAlarmButtonInteraction(app); + } + filter(...grahpics: JlGraphic[]): ManualAlarmButton[] | undefined { + return grahpics + .filter((g) => g.type === ManualAlarmButton.Type) + .map((g) => g as ManualAlarmButton); + } + bind(g: ManualAlarmButton): void { + g.eventMode = 'static'; + g.cursor = 'pointer'; + g.scalable = true; + g.rotatable = true; + g.on('transformstart', this.transformstart, this); + } + unbind(g: ManualAlarmButton): void { + g.eventMode = 'none'; + g.scalable = false; + g.rotatable = false; + g.off('transformstart', this.transformstart, this); + } + transformstart(e: GraphicTransformEvent) { + const target = e.target as DisplayObject; + const manualAlarmButton = target.getGraphic() as ManualAlarmButton; + manualAlarmButton.getGraphicApp().setOptions({ + absorbablePositions: buildAbsorbablePositions(manualAlarmButton), + }); + } +} diff --git a/src/graphics/FAS/smokeDetector/SmokeDetector.json b/src/graphics/FAS/smokeDetector/SmokeDetector.json new file mode 100644 index 0000000..f3f9546 --- /dev/null +++ b/src/graphics/FAS/smokeDetector/SmokeDetector.json @@ -0,0 +1,21 @@ +{ + "frames": { + "normal.png": { + "frame": { "x": 0, "y": 0, "w": 21, "h": 11 }, + "rotated": false, + "trimmed": false, + "spriteSourceSize": { "x": 0, "y": 0, "w": 21, "h": 11 }, + "sourceSize": { "w": 21, "h": 11 }, + "anchor": { "x": 0.5, "y": 0.5 } + } + }, + "meta": { + "app": "https://www.codeandweb.com/texturepacker", + "version": "1.1", + "image": "SmokeDetector.png", + "format": "RGBA8888", + "size": { "w": 21, "h": 11 }, + "scale": "1", + "smartupdate": "$TexturePacker:SmartUpdate:e7620bd2d73cc0b3e2deea9704e7eefc:f129a1d9e4b9ba57720b3861c22b155b:eb2d421f7759984b7713aa4aa5354134$" + } +} diff --git a/src/graphics/FAS/smokeDetector/SmokeDetector.png b/src/graphics/FAS/smokeDetector/SmokeDetector.png new file mode 100644 index 0000000000000000000000000000000000000000..debcf835afd7333a371c9018f302534472c95048 GIT binary patch literal 650 zcmV;50(Jd~P)VHAh)|61?6ojsrFq>NzB=ond9iu83*K}2Gq zG;>f;9YoM=bQRq|2SGv9LD5kWL0}k!6+sCimf#0DjgF)9vG;!0>R`HnAJ0QG561R0 zm3V&$->E8#iC6()Wg#IUf(ToNQ&oZ$QigzSPz}0va(3zOPZ+Tcf~YtMvvI;;B`Aad zB|xD7gH;6p7{rhUw<^o_Qs!nMUpziB;-?epR3M}vB83APapVz19WzIOaA?H?h^$*% z*;)*L*kb&2{d?p0dfT(sh#@i*kb+3N#6+G^*YcH{P-9^tpDB{i3uC^i?wCUS6gd~Z zc=_tx>$hJQKh?Pwgl!ybs2H+QxNFTG=|G!9%YazHS|XP6yjE(oaN^dT+tmvv z)WheWZ8GT=1}pKZO4t+Snk^eXN=JKboA9&lkcr~0C7L;Z(T^Db05bpp3QS+S(w`h? zrZ@VsMSsY}2Vr}o^norj5XJN27qutZ9c6dBO<(!OEVSc<0Re%)xm@n@nXB!Z+i%pd zl4@>8;XZ<9;I_C~bKZLQ_Rg+r)48J;@`Yhg$Fl`G3j%PdRQgbVmPn_LAXgb(j{nLA z8=jjq)_Q%bhbw#AwQ8+2TZRJk|G)xJRU!s3GBP}_)AMgW`egO}u?CP7nb90CY1CeSl2MH2?qr07*qoM6N<$f;#^q0{{R3 literal 0 HcmV?d00001 diff --git a/src/graphics/FAS/smokeDetector/SmokeDetector.ts b/src/graphics/FAS/smokeDetector/SmokeDetector.ts new file mode 100644 index 0000000..5426141 --- /dev/null +++ b/src/graphics/FAS/smokeDetector/SmokeDetector.ts @@ -0,0 +1,63 @@ +import { GraphicData, JlGraphic, JlGraphicTemplate } from 'jl-graphic'; +import { Assets, Sprite, Spritesheet, Texture } from 'pixi.js'; +// import { iscsGraphicData } from 'src/protos/iscs_graphic_data'; +import SmokeDetectorJson from './SmokeDetector.json'; +import SmokeDetectorAsset from './SmokeDetector.png'; + +export interface ISmokeDetectorData extends GraphicData { + get code(): string; + set code(v: string); +} + +interface SmokeDetectorTextures { + normal: Texture; +} + +export class SmokeDetector extends JlGraphic { + static Type = 'SmokeDetector'; + _smokeDetector: Sprite; + smokeDetectorTextures: SmokeDetectorTextures; + __state = 0; + + constructor(smokeDetectorTextures: SmokeDetectorTextures) { + super(SmokeDetector.Type); + this._smokeDetector = new Sprite(); + this.smokeDetectorTextures = smokeDetectorTextures; + this._smokeDetector.anchor.set(0.5); + this.addChild(this._smokeDetector); + this._smokeDetector.texture = this.smokeDetectorTextures.normal; + } + get code(): string { + return this.datas.code; + } + get datas(): ISmokeDetectorData { + return this.getDatas(); + } + + doRepaint(): void {} +} + +export class SmokeDetectorTemplate extends JlGraphicTemplate { + smokeDetectorTextures?: SmokeDetectorTextures; + constructor(dataTemplate: ISmokeDetectorData) { + super(SmokeDetector.Type, { dataTemplate }); + this.loadAssets(); + } + new(): SmokeDetector { + if (this.smokeDetectorTextures) { + const g = new SmokeDetector(this.smokeDetectorTextures); + g.loadData(this.datas); + return g; + } + throw new Error('资源未加载/加载失败'); + } + async loadAssets(): Promise { + const texture = await Assets.load(SmokeDetectorAsset); + const smokeDetectorSheet = new Spritesheet(texture, SmokeDetectorJson); + const result = await smokeDetectorSheet.parse(); + this.smokeDetectorTextures = { + normal: result['normal.png'], + }; + return this.smokeDetectorTextures as SmokeDetectorTextures; + } +} diff --git a/src/graphics/FAS/smokeDetector/SmokeDetectorAssistant.ts b/src/graphics/FAS/smokeDetector/SmokeDetectorAssistant.ts new file mode 100644 index 0000000..b82ec90 --- /dev/null +++ b/src/graphics/FAS/smokeDetector/SmokeDetectorAssistant.ts @@ -0,0 +1,123 @@ +import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js'; +import { + AbsorbableLine, + AbsorbablePosition, + GraphicDrawAssistant, + GraphicInteractionPlugin, + GraphicTransformEvent, + IDrawApp, + JlGraphic, +} from 'jl-graphic'; +import { + ISmokeDetectorData, + SmokeDetector, + SmokeDetectorTemplate, +} from './SmokeDetector'; + +export class SmokeDetectorDraw extends GraphicDrawAssistant< + SmokeDetectorTemplate, + ISmokeDetectorData +> { + _smokeDetector: SmokeDetector | null = null; + constructor(app: IDrawApp, template: SmokeDetectorTemplate) { + super(app, template, 'svguse:../drawIcon.svg#icon-smoke-detector', '烟感'); + SmokeDetectorInteraction.init(app); + } + + bind(): void { + super.bind(); + if (!this._smokeDetector) { + this._smokeDetector = this.graphicTemplate.new(); + this.container.addChild(this._smokeDetector); + } + } + + public get smokeDetector(): SmokeDetector { + if (!this._smokeDetector) { + this._smokeDetector = this.graphicTemplate.new(); + this.container.addChild(this._smokeDetector); + } + return this._smokeDetector; + } + + redraw(cp: Point): void { + this.smokeDetector.position.copyFrom(cp); + } + onLeftUp(e: FederatedMouseEvent): void { + this.smokeDetector.position.copyFrom(this.toCanvasCoordinates(e.global)); + this.createAndStore(true); + } + prepareData(data: ISmokeDetectorData): boolean { + data.transform = this.smokeDetector.saveTransform(); + return true; + } + onEsc(): void { + this.finish(); + } +} + +/** + * 构建吸附线 + * @param smokeDetector + */ +function buildAbsorbablePositions( + smokeDetector: SmokeDetector +): AbsorbablePosition[] { + const aps: AbsorbablePosition[] = []; + const smokeDetectors = smokeDetector.queryStore.queryByType( + SmokeDetector.Type + ); + const canvas = smokeDetector.getCanvas(); + smokeDetectors.forEach((item) => { + if (item.id === smokeDetector.id) { + return; + } + const ala = new AbsorbableLine( + new Point(item.x, 0), + new Point(item.x, canvas.height) + ); + const alb = new AbsorbableLine( + new Point(0, item.y), + new Point(canvas.width, item.y) + ); + aps.push(ala); + aps.push(alb); + }); + + return aps; +} + +export class SmokeDetectorInteraction extends GraphicInteractionPlugin { + static Name = 'smoke_detector_transform'; + constructor(app: IDrawApp) { + super(SmokeDetectorInteraction.Name, app); + } + static init(app: IDrawApp) { + return new SmokeDetectorInteraction(app); + } + filter(...grahpics: JlGraphic[]): SmokeDetector[] | undefined { + return grahpics + .filter((g) => g.type === SmokeDetector.Type) + .map((g) => g as SmokeDetector); + } + bind(g: SmokeDetector): void { + g.eventMode = 'static'; + g.cursor = 'pointer'; + g.scalable = true; + g.rotatable = true; + g.on('transformstart', this.transformstart, this); + } + unbind(g: SmokeDetector): void { + g.eventMode = 'none'; + g.scalable = false; + g.rotatable = false; + g.off('transformstart', this.transformstart, this); + } + transformstart(e: GraphicTransformEvent) { + const target = e.target as DisplayObject; + const smokeDetector = target.getGraphic() as SmokeDetector; + smokeDetector.getGraphicApp().setOptions({ + absorbablePositions: buildAbsorbablePositions(smokeDetector), + }); + } +} diff --git a/src/layouts/IscsDrawLayout.vue b/src/layouts/IscsDrawLayout.vue index 088a095..0e432dc 100644 --- a/src/layouts/IscsDrawLayout.vue +++ b/src/layouts/IscsDrawLayout.vue @@ -308,6 +308,8 @@ import CCTVMonitoring from 'src/components/Iscs/CCTVMonitoring.vue'; import FASPlaneGraph from 'src/components/Iscs/FASPlaneGraph.vue'; import { FasFailureControlHost } from 'src/graphics/FAS/fireFailureControlHost/FasFailureControlHost'; import { FasAlarm } from 'src/graphics/FAS/fasAlarm/FasAlarm'; +import { ManualAlarmButton } from 'src/graphics/FAS/manualAlarmButton/ManualAlarmButton'; +import { SmokeDetector } from 'src/graphics/FAS/smokeDetector/SmokeDetector'; const $q = useQuasar(); const route = useRoute(); @@ -394,6 +396,8 @@ function handleUtilsOption() { case '火灾报警平面图': drawAssistantsTypes.push(FasFailureControlHost.Type); drawAssistantsTypes.push(FasAlarm.Type); + drawAssistantsTypes.push(ManualAlarmButton.Type); + drawAssistantsTypes.push(SmokeDetector.Type); break; } drawAssistantsTypes.forEach((type) => {