From 27c8ceb1db45fa3a96a52f573eb74756859de275 Mon Sep 17 00:00:00 2001 From: alivender <13898766233@163.com> Date: Sun, 20 Jul 2025 10:33:57 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E4=B8=83?= =?UTF-8?q?=E6=AE=B5=E6=95=B0=E7=A0=81=E7=AE=A1=E7=9A=84=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../equipments/SevenSegmentDisplay.vue | 145 ++++++++++++++++-- 1 file changed, 134 insertions(+), 11 deletions(-) diff --git a/src/components/equipments/SevenSegmentDisplay.vue b/src/components/equipments/SevenSegmentDisplay.vue index e7a251e..3a5475b 100644 --- a/src/components/equipments/SevenSegmentDisplay.vue +++ b/src/components/equipments/SevenSegmentDisplay.vue @@ -79,6 +79,7 @@ interface SevenSegmentDisplayProps { size?: number; color?: string; AFTERGLOW_BUFFER_SIZE?: number; // 余晖存储槽大小 + AFTERGLOW_DURATION?: number; // 余晖持续时间(毫秒) pins?: { pinId: string; constraint: string; @@ -92,7 +93,7 @@ const props = withDefaults(defineProps(), { size: 1, color: "red", AFTERGLOW_BUFFER_SIZE: 1, // 默认存储槽大小为100 - AFTERGLOW_UPDATE_INTERVAL: 5, // 默认更新间隔为2毫秒 + AFTERGLOW_DURATION: 2000, // 默认余晖持续时间500毫秒 cathodeType: "common", // 默认为共阴极 pins: () => [ { pinId: "a", constraint: "", x: 10, y: 170 }, // a段 @@ -149,7 +150,7 @@ const afterglowBuffers = ref>({ }); // 余晖判定阈值(比如持续10帧才算稳定,可根据刷新间隔和人眼余晖调节) -const STABLE_THRESHOLD = 10; +const STABLE_THRESHOLD = 3; // 实际显示的段状态(只有稳定后才改变) const stableSegmentStates = ref({ @@ -175,10 +176,54 @@ const segmentStableCounters = ref>({ dp: 0, }); -// 判断段是否激活(用稳定状态) +// 段选关闭时的余晖状态保持 +const afterglowStates = ref({ + a: false, + b: false, + c: false, + d: false, + e: false, + f: false, + g: false, + dp: false, +}); + +// 余晖计时器 +const afterglowTimers = ref>({ + a: null, + b: null, + c: null, + d: null, + e: null, + f: null, + g: null, + dp: null, +}); + +// 余晖持续时间(毫秒) +const AFTERGLOW_DURATION = computed(() => props.AFTERGLOW_DURATION || 500); + +// 当前COM口状态 +const currentComActive = ref(false); // 初始化为false,等待第一次状态检查 + +// 是否处于余晖模式 +const isInAfterglowMode = ref(false); + +// 判断段是否激活(用稳定状态或余晖状态) function isSegmentActive( segment: "a" | "b" | "c" | "d" | "e" | "f" | "g" | "dp", ): boolean { + // 如果处于余晖模式,使用余晖状态 + if (isInAfterglowMode.value) { + return afterglowStates.value[segment]; + } + + // 如果COM口未激活,所有段都不显示 + if (!currentComActive.value) { + return false; + } + + // 否则使用稳定状态 return stableSegmentStates.value[segment]; } @@ -186,21 +231,45 @@ function isSegmentActive( function updateSegmentStates() { // 先获取COM口状态 const comPin = props.pins.find((p) => p.pinId === "COM"); - let comActive = true; + let comActive = false; // 默认未激活 + if (comPin && comPin.constraint) { const comState = getConstraintState(comPin.constraint); if (props.cathodeType === "anode") { - // anode模式下,COM为高电平则所有段都熄灭 - comActive = comState !== "high"; + // 共阳极模式下,COM为低电平才激活 + comActive = comState === "low"; + } else { + // 共阴极模式下,COM为低电平才激活 + comActive = comState === "low"; } - // 可扩展其他模式 + } else if (!comPin || !comPin.constraint) { + // 如果没有COM引脚或者COM引脚没有约束,则认为始终激活 + comActive = true; } - // 如果COM口激活,更新所有段的状态到存储槽 - if (comActive) { - updateAfterglowBuffers(); + // 检查COM口状态是否发生变化 + const comStateChanged = currentComActive.value !== comActive; + currentComActive.value = comActive; + + // 如果COM从激活变为非激活,进入余晖模式 + if (comStateChanged && !comActive) { + enterAfterglowMode(); + return; // 在余晖模式下,不处理其他引脚变化 } + // 如果COM从非激活变为激活,退出余晖模式 + if (comStateChanged && comActive) { + exitAfterglowMode(); + } + + // 关键修复:如果COM口未激活或处于余晖模式,不处理任何引脚状态变化 + if (!comActive || isInAfterglowMode.value) { + return; + } + + // 只有当COM口激活时,才更新段的状态 + updateAfterglowBuffers(); + // 先更新 segmentStates for (const pin of props.pins) { if (["a", "b", "c", "d", "e", "f", "g", "dp"].includes(pin.pinId)) { @@ -215,7 +284,8 @@ function updateSegmentStates() { } else { newState = pinState === "low"; } - segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = newState && comActive; + // 段状态只有在COM激活时才有效 + segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = newState; } } @@ -255,6 +325,49 @@ function updateAfterglowBuffers() { } } +// 进入余晖模式 +function enterAfterglowMode() { + isInAfterglowMode.value = true; + + // 保存当前稳定状态作为余晖状态 + for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) { + const typedSegmentId = segmentId as keyof typeof stableSegmentStates.value; + afterglowStates.value[typedSegmentId] = stableSegmentStates.value[typedSegmentId]; + + // 设置定时器,在余晖持续时间后退出余晖模式 + if (afterglowTimers.value[segmentId]) { + clearTimeout(afterglowTimers.value[segmentId]!); + } + + afterglowTimers.value[segmentId] = setTimeout(() => { + afterglowStates.value[typedSegmentId] = false; + + // 检查是否所有段都已经关闭 + const allSegmentsOff = Object.values(afterglowStates.value).every(state => !state); + if (allSegmentsOff) { + exitAfterglowMode(); + } + }, AFTERGLOW_DURATION.value); + } +} + +// 退出余晖模式 +function exitAfterglowMode() { + isInAfterglowMode.value = false; + + // 清除所有定时器 + for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) { + if (afterglowTimers.value[segmentId]) { + clearTimeout(afterglowTimers.value[segmentId]!); + afterglowTimers.value[segmentId] = null; + } + + // 重置余晖状态 + const typedSegmentId = segmentId as keyof typeof afterglowStates.value; + afterglowStates.value[typedSegmentId] = false; + } +} + // 监听约束状态变化 function onConstraintChange(constraint: string, level: string) { const affectedPin = props.pins.find((pin) => pin.constraint === constraint); @@ -276,6 +389,15 @@ onMounted(() => { onConstraintStateChange(onConstraintChange); }); +onUnmounted(() => { + // 清理所有余晖定时器 + for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) { + if (afterglowTimers.value[segmentId]) { + clearTimeout(afterglowTimers.value[segmentId]!); + } + } +}); + // 暴露属性和方法 defineExpose({ updateSegmentStates, @@ -307,6 +429,7 @@ export function getDefaultProps() { size: 1, color: "red", cathodeType: "common", + AFTERGLOW_DURATION: 500, // 默认余晖持续时间500毫秒 pins: [ { pinId: "a", constraint: "", x: 10, y: 170 }, { pinId: "b", constraint: "", x: 25 - 1, y: 170 },