|
|
@@ -7313,6 +7313,31 @@
|
|
|
fill="none"
|
|
|
d="
M 17567.8 5512.9
L 17647.25 5603"
|
|
|
/>
|
|
|
+
|
|
|
+ <g id="Mask_Main_9_a_FILL">
|
|
|
+ <path fill="#FFFFFF" stroke="none" d="M 746.15 471.26 L 67.03 569.48 L 70.43 592.93 L 749.54 494.71 Z" />
|
|
|
+ </g>
|
|
|
+ <g id="Mask_Main_9_b_FILL">
|
|
|
+ <path fill="#FFFFFF" stroke="none" d="M 1027.07 454.57 L 1023.68 431.12 L 746.15 471.26 L 749.54 494.71 L 1027.07 454.57 Z" />
|
|
|
+ </g>
|
|
|
+ <g id="Mask_Main_19_a_FILL">
|
|
|
+ <path fill="#FFFFFF" stroke="none" d="M 469.16 421.16 L 67.25 470.4 L 69.35 487.65 L 471.27 438.41 Z" />
|
|
|
+ </g>
|
|
|
+ <g id="Mask_Main_19_b_FILL">
|
|
|
+ <path fill="#FFFFFF" stroke="none" d="M 862.8 390.45 L 860.7 373.2 L 469.16 421.16 L 471.27 438.41 L 862.8 390.45 Z" />
|
|
|
+ </g>
|
|
|
+ <g id="Mask_Main_7_a_FILL">
|
|
|
+ <path fill="#FFFFFF" stroke="none" d="M 574.33 635.55 L 517 648.25 L 521 661.95 L 577.43 649.57 Z" />
|
|
|
+ </g>
|
|
|
+ <g id="Mask_Main_7_b_FILL">
|
|
|
+ <path fill="#FFFFFF" stroke="none" d="M 940.55 569.95 L 937.3 555.15 L 574.33 635.55 L 577.43 649.57 L 940.55 569.95 Z" />
|
|
|
+ </g>
|
|
|
+ <g id="Mask_Main_8_a_FILL">
|
|
|
+ <path fill="#FFFFFF" stroke="none" d="M 627.1 642.68 L 429.85 687.2 L 430.85 702.15 L 630.34 656.98 Z" />
|
|
|
+ </g>
|
|
|
+ <g id="Mask_Main_8_b_FILL">
|
|
|
+ <path fill="#FFFFFF" stroke="none" d="M 994.2 574.6 L 991.05 560.55 L 627.1 642.68 L 630.34 656.98 L 994.2 574.6 Z" />
|
|
|
+ </g>
|
|
|
</defs>
|
|
|
<g transform="matrix( 0.053741455078125, 0, 0, 0.053741455078125, 11.4,265.3) ">
|
|
|
<g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
@@ -8280,6 +8305,48 @@
|
|
|
</g>
|
|
|
</g>
|
|
|
</g>
|
|
|
+
|
|
|
+ <mask id="Mask_Main_9_a">
|
|
|
+ <g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
+ <use xlink:href="#Mask_Main_9_a_FILL" />
|
|
|
+ </g>
|
|
|
+ </mask>
|
|
|
+ <mask id="Mask_Main_9_b">
|
|
|
+ <g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
+ <use xlink:href="#Mask_Main_9_b_FILL" />
|
|
|
+ </g>
|
|
|
+ </mask>
|
|
|
+ <mask id="Mask_Main_19_a">
|
|
|
+ <g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
+ <use xlink:href="#Mask_Main_19_a_FILL" />
|
|
|
+ </g>
|
|
|
+ </mask>
|
|
|
+ <mask id="Mask_Main_19_b">
|
|
|
+ <g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
+ <use xlink:href="#Mask_Main_19_b_FILL" />
|
|
|
+ </g>
|
|
|
+ </mask>
|
|
|
+ <mask id="Mask_Main_7_a">
|
|
|
+ <g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
+ <use xlink:href="#Mask_Main_7_a_FILL" />
|
|
|
+ </g>
|
|
|
+ </mask>
|
|
|
+ <mask id="Mask_Main_7_b">
|
|
|
+ <g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
+ <use xlink:href="#Mask_Main_7_b_FILL" />
|
|
|
+ </g>
|
|
|
+ </mask>
|
|
|
+ <mask id="Mask_Main_8_a">
|
|
|
+ <g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
+ <use xlink:href="#Mask_Main_8_a_FILL" />
|
|
|
+ </g>
|
|
|
+ </mask>
|
|
|
+ <mask id="Mask_Main_8_b">
|
|
|
+ <g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
+ <use xlink:href="#Mask_Main_8_b_FILL" />
|
|
|
+ </g>
|
|
|
+ </mask>
|
|
|
+
|
|
|
<mask id="Mask_Mask_1">
|
|
|
<g transform="matrix( 1, 0, 0, 1, 0,0) ">
|
|
|
<use xlink:href="#Mask_39_MASK_0_FILL" />
|
|
|
@@ -8407,11 +8474,11 @@
|
|
|
* 36 个动画元素里有 31 个真有位移,另 5 个(9/11/12/13/15/16 中的 9/11/12/13/16)只是生成器
|
|
|
* 把 0.1~0.2px 的浮点舍入当成了变化,因此不参与动画、保持静止。
|
|
|
*
|
|
|
- * 2) 与三维 handleAnimation 同源:子组件在轮询里调 animate2D(data),传的就是给三维 playAnimate
|
|
|
- * 的同一份监测数据。判定口径与三维逐字一致 —— 优先用该站注入的"泵号 → 运行点位"
|
|
|
- * (getPumpRunSignals(deviceType),布尔台新站变频器状态 / 老站磁力启动器断路器状态),
|
|
|
- * 未注入时回落到进气/出气阀门开度(jqf1/cqf1、jqf2/cqf2);先全部不点亮,
|
|
|
- * 再只点亮运行中泵所接的管路(与三维"先隐藏、再点亮"完全对应)。
|
|
|
+ * 2) 动画分组按"泵号 + 管路 → mask"渲染(PUMP_PIPE_MASKS,见下方):
|
|
|
+ * 1 号泵用整段总管(9/19/8/7),2 号泵用按接入节点切出的分段总管(9a/19a/8a/7a),
|
|
|
+ * 各泵自己的支管段各自成组;运行时把对应分组点亮并播放,其余分组停住并隐藏。
|
|
|
+ * 泵运行与否的判定与三维 handleAnimation 同源:优先用该站注入的"泵号 → 运行点位"
|
|
|
+ * (getPumpRunSignals(deviceType)),未注入时回落到进气/出气阀门开度(jqf/cqf)。
|
|
|
*/
|
|
|
const elementInfo = new Map([
|
|
|
[
|
|
|
@@ -9107,27 +9174,12 @@
|
|
|
*/
|
|
|
const UNLIT_OPACITY = '0';
|
|
|
|
|
|
- /** 有位移、需要参与动画的元素序号(其余保持静止) */
|
|
|
- const MOVING = [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35];
|
|
|
-
|
|
|
- /**
|
|
|
- * 泵号 → 参与该泵流动的元素序号
|
|
|
- *
|
|
|
- * 与三维 pumpArrows 表同一个思路(每台泵一组管路),现场若与左右相反,只改这两行即可。
|
|
|
- */
|
|
|
- const PUMP_FLOW_ELEMENTS: Record<number, number[]> = {
|
|
|
- 1: [2, 3, 4, 5, 6, 25, 26, 30, 31, 32, 33],
|
|
|
- 2: [0, 1, 19, 20, 21, 22, 23, 24, 27, 28, 29, 35],
|
|
|
- };
|
|
|
-
|
|
|
- /** 跨区总管/共用管路(二维版面特有):任一台泵运行就应该流动 */
|
|
|
- const SHARED_FLOW_ELEMENTS = [7, 8, 10, 14, 15, 17, 18, 34];
|
|
|
-
|
|
|
- /** 回落口径用的标签表(与三维同一张表) */
|
|
|
+ /** 回落口径用的标签表(与三维同一张表:按 domId 取该站的点位) */
|
|
|
const modelMonitorTags = getModelMonitorTags();
|
|
|
|
|
|
- /** 当前站型的"泵号 → 运行点位",随 deviceType 解析并缓存 */
|
|
|
+ /** 当前站型的“泵号 → 运行点位”,随 deviceType 解析并缓存 */
|
|
|
const runSignals = ref<Record<number, { code: string }> | null>(null);
|
|
|
+
|
|
|
/** 上一次收到的监测数据:站型变化或运行点位解析完成后,用它立刻重刷一次 */
|
|
|
let lastData: any = null;
|
|
|
|
|
|
@@ -9143,22 +9195,115 @@
|
|
|
return el ? [el] : [];
|
|
|
}
|
|
|
|
|
|
- /** 按"每台泵是否运行"批量应用到分组:运行=继续流动,未运行=停住并隐藏 */
|
|
|
- function applyPumps(pumps: Record<number, boolean>) {
|
|
|
- MOVING.forEach((n) => {
|
|
|
- const els = elementsOf(n);
|
|
|
- if (!els.length) return;
|
|
|
+ /**
|
|
|
+ * mask 编号 → 该 mask 覆盖的动画分组(auto_anim_N 的 N)
|
|
|
+ *
|
|
|
+ * 与源素材一一对应:Mask_Mask_1 → 0、Mask_Mask_2 → 1 …… 一个 mask 里的多个分组是同一条管道
|
|
|
+ * 的不同段(横管/立管/弯头),所以一条 mask 会带多个分组编号。带 a 的分段 mask 与整段共用同一批分组。
|
|
|
+ */
|
|
|
+ const MASK_GROUPS: Record<string, number[]> = {
|
|
|
+ '1': [0],
|
|
|
+ '2': [1],
|
|
|
+ '3': [2],
|
|
|
+ '4': [3],
|
|
|
+ '5': [4, 5],
|
|
|
+ '6': [6],
|
|
|
+ '7': [7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
|
|
|
+ '8': [17],
|
|
|
+ '9': [18],
|
|
|
+ '10': [19, 20, 21, 22, 23],
|
|
|
+ '11': [24],
|
|
|
+ '12': [25],
|
|
|
+ '13': [26],
|
|
|
+ '14': [27],
|
|
|
+ '15': [28, 29],
|
|
|
+ '16': [30],
|
|
|
+ '17': [31],
|
|
|
+ '18': [32, 33],
|
|
|
+ '19': [34],
|
|
|
+ '20': [35],
|
|
|
+ };
|
|
|
|
|
|
- const shared = SHARED_FLOW_ELEMENTS.includes(n);
|
|
|
- const lit = shared
|
|
|
- ? Object.values(pumps).some(Boolean) // 共用管路:任一台泵运行就流动
|
|
|
- : Object.entries(PUMP_FLOW_ELEMENTS).some(([pumpNo, list]) => pumps[Number(pumpNo)] && list.includes(n));
|
|
|
+ /**
|
|
|
+ * 泵号 + 管路 → 使用哪些 mask(现场给定的分组规则)
|
|
|
+ *
|
|
|
+ * 带 a 的是按节点切出来的分段 mask(9a/19a/8a/7a):2 号泵接在总管中段,
|
|
|
+ * 所以总管只画到它接入的节点为止;1 号泵接在总管靠外侧,用整段。
|
|
|
+ */
|
|
|
+ const PUMP_PIPE_MASKS: Record<number, Record<string, string[]>> = {
|
|
|
+ 1: {
|
|
|
+ airIn: ['9', '10', '11'],
|
|
|
+ airOut: ['14', '15', '19', '20'],
|
|
|
+ waterIn: ['1', '8'],
|
|
|
+ waterOut: ['2', '5', '6', '7'],
|
|
|
+ },
|
|
|
+ 2: {
|
|
|
+ airIn: ['9a', '12', '13'],
|
|
|
+ airOut: ['16', '17', '18', '19a'],
|
|
|
+ waterIn: ['3', '8a'],
|
|
|
+ waterOut: ['4', '5', '6', '7a'],
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 分段 mask 编号 → 组件里实际定义的 mask id(其余按 Mask_Mask_<编号> 取) */
|
|
|
+ const SPLIT_MASK_ID: Record<string, string> = {
|
|
|
+ '9a': 'Mask_Main_9_a',
|
|
|
+ '19a': 'Mask_Main_19_a',
|
|
|
+ '8a': 'Mask_Main_8_a',
|
|
|
+ '7a': 'Mask_Main_7_a',
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 四条管路(与 PUMP_PIPE_MASKS 的键一致) */
|
|
|
+ const PIPE_KEYS = ['airIn', 'airOut', 'waterIn', 'waterOut'];
|
|
|
+
|
|
|
+ /** 分组编号 → 它原本挂的整段 mask;同时给出需要参与控制的全部分组 */
|
|
|
+ const MASK_BY_GROUP: Record<number, string> = {};
|
|
|
+ Object.entries(MASK_GROUPS).forEach(([key, list]) => list.forEach((n) => (MASK_BY_GROUP[n] = `Mask_Mask_${key}`)));
|
|
|
+ const ALL_GROUPS = Object.keys(MASK_BY_GROUP).map(Number);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 点亮 / 熄灭一个分组
|
|
|
+ *
|
|
|
+ * @param maskKey 该分组这次用的 mask 编号;传 null 表示这次不点亮(停住并隐藏)
|
|
|
+ * 带 a 的分段 mask 会把包裹层的 mask 属性换成对应的分段 mask,
|
|
|
+ * 不点亮或整段时恢复成它原本的 mask。
|
|
|
+ */
|
|
|
+ function setGroup(n: number, maskKey: string | null) {
|
|
|
+ const els = elementsOf(n);
|
|
|
+ if (!els.length) return;
|
|
|
+ const base = MASK_BY_GROUP[n];
|
|
|
+ const want = !maskKey ? base : SPLIT_MASK_ID[maskKey] || base;
|
|
|
+ els.forEach((el) => {
|
|
|
+ el.style.animationPlayState = maskKey ? 'running' : 'paused';
|
|
|
+ el.style.opacity = maskKey ? '' : UNLIT_OPACITY;
|
|
|
+ const wrapper = el.parentElement; // 带 mask 属性的那层(管道裁剪窗口)
|
|
|
+ if (!wrapper || !wrapper.getAttribute('mask')) return;
|
|
|
+ const value = `url(#${want})`;
|
|
|
+ if (wrapper.getAttribute('mask') !== value) wrapper.setAttribute('mask', value);
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- els.forEach((el) => {
|
|
|
- el.style.animationPlayState = lit ? 'running' : 'paused';
|
|
|
- el.style.opacity = lit ? '' : UNLIT_OPACITY;
|
|
|
+ /**
|
|
|
+ * 按"每台泵是否运行"渲染:先算出每个分组这次用哪条 mask,再统一点亮/熄灭
|
|
|
+ *
|
|
|
+ * 同一分组可能被多台泵/多条管路同时引用(比如 5、6、7 段两条出水都用),
|
|
|
+ * 这里整段优先于分段;两台泵都运行时取并集(现场不会同时运行,仅作兜底)。
|
|
|
+ */
|
|
|
+ function applyPumps(pumps: Record<number, boolean>) {
|
|
|
+ const plan = new Map<number, string>();
|
|
|
+ ([1, 2] as const).forEach((pumpNo) => {
|
|
|
+ if (!pumps[pumpNo]) return;
|
|
|
+ PIPE_KEYS.forEach((pipe) => {
|
|
|
+ (PUMP_PIPE_MASKS[pumpNo][pipe] || []).forEach((maskKey) => {
|
|
|
+ const groups = MASK_GROUPS[maskKey.replace(/a$/, '')] || [];
|
|
|
+ groups.forEach((n) => {
|
|
|
+ const cur = plan.get(n);
|
|
|
+ if (cur === undefined || (cur.endsWith('a') && !maskKey.endsWith('a'))) plan.set(n, maskKey);
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
});
|
|
|
+ ALL_GROUPS.forEach((n) => setGroup(n, plan.get(n) ?? null));
|
|
|
}
|
|
|
|
|
|
/** 从监测数据算每台泵是否运行(判定口径与三维 isPumpRunning 完全一致) */
|
|
|
@@ -9175,9 +9320,12 @@
|
|
|
* @param payload 子组件轮询得到的监测数据;内部按"泵号 → 运行点位"(未注入时回落到阀门开度)
|
|
|
* 判定每台泵是否运行,先全部不点亮再只点亮运行中泵所接的管路。
|
|
|
* 也兼容直接给 { pumps: { 1: true, 2: false } }(便于测试/兜底)。
|
|
|
- * 不传或数据为空 → 全部不点亮,与三维"未注入运行状态就不点亮箭头"一致。
|
|
|
+ * 与三维 handleAnimation 对齐:不传数据(undefined/null)→ 保持上一次状态;
|
|
|
+ * 传空对象/空数据 → 全部熄灭(先隐藏、再只点亮运行中泵的管路)。
|
|
|
*/
|
|
|
- function animate(payload: any = {}) {
|
|
|
+ function animate(payload?: any) {
|
|
|
+ // 与三维 handleAnimation 一致:没传数据(undefined/null)就保持上一次状态,不把画面清空
|
|
|
+ if (!payload) return;
|
|
|
lastData = payload;
|
|
|
// 兼容直接给 { pumps } 的调用(监测数据里不会出现 pumps 字段,所以这样判不会误判)
|
|
|
if (payload && typeof payload === 'object' && Object.prototype.hasOwnProperty.call(payload, 'pumps')) {
|