feat: optimize segment
This commit is contained in:
		@@ -78,7 +78,8 @@ const pinRefs = ref<Record<string, any>>({});
 | 
			
		||||
interface SevenSegmentDisplayProps {
 | 
			
		||||
  size?: number;
 | 
			
		||||
  color?: string;
 | 
			
		||||
  AFTERGLOW_DURATION?: number; // 余晖持续时间,单位毫秒
 | 
			
		||||
  AFTERGLOW_BUFFER_SIZE?: number; // 余晖存储槽大小
 | 
			
		||||
  AFTERGLOW_UPDATE_INTERVAL?: number; // 余晖更新间隔,单位毫秒
 | 
			
		||||
  pins?: {
 | 
			
		||||
    pinId: string;
 | 
			
		||||
    constraint: string;
 | 
			
		||||
@@ -91,6 +92,8 @@ interface SevenSegmentDisplayProps {
 | 
			
		||||
const props = withDefaults(defineProps<SevenSegmentDisplayProps>(), {
 | 
			
		||||
  size: 1,
 | 
			
		||||
  color: "red",
 | 
			
		||||
  AFTERGLOW_BUFFER_SIZE: 1, // 默认存储槽大小为100
 | 
			
		||||
  AFTERGLOW_UPDATE_INTERVAL: 1, // 默认更新间隔为2毫秒
 | 
			
		||||
  cathodeType: "common", // 默认为共阴极
 | 
			
		||||
  pins: () => [
 | 
			
		||||
    { pinId: "a", constraint: "", x: 10, y: 170 }, // a段
 | 
			
		||||
@@ -122,7 +125,7 @@ watch(
 | 
			
		||||
  { deep: true },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
// 段引脚状态
 | 
			
		||||
// 段引脚的当前状态
 | 
			
		||||
const segmentStates = ref({
 | 
			
		||||
  a: false,
 | 
			
		||||
  b: false,
 | 
			
		||||
@@ -134,26 +137,26 @@ const segmentStates = ref({
 | 
			
		||||
  dp: false,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 余晖状态
 | 
			
		||||
const afterglowStates = ref({
 | 
			
		||||
  a: false,
 | 
			
		||||
  b: false,
 | 
			
		||||
  c: false,
 | 
			
		||||
  d: false,
 | 
			
		||||
  e: false,
 | 
			
		||||
  f: false,
 | 
			
		||||
  g: false,
 | 
			
		||||
  dp: false,
 | 
			
		||||
// 余晖存储槽 - 每个段有一个存储槽数组,存储历史状态
 | 
			
		||||
const afterglowBuffers = ref<Record<string, boolean[]>>({
 | 
			
		||||
  a: [],
 | 
			
		||||
  b: [],
 | 
			
		||||
  c: [],
 | 
			
		||||
  d: [],
 | 
			
		||||
  e: [],
 | 
			
		||||
  f: [],
 | 
			
		||||
  g: [],
 | 
			
		||||
  dp: [],
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 余晖定时器
 | 
			
		||||
const afterglowTimers = ref<Record<string, number>>({});
 | 
			
		||||
// 更新间隔计时器
 | 
			
		||||
let updateIntervalTimer: number | null = null;
 | 
			
		||||
 | 
			
		||||
// 判断段是否激活
 | 
			
		||||
// 判断段是否激活 - 如果当前状态或任一历史状态为true,则视为激活
 | 
			
		||||
function isSegmentActive(
 | 
			
		||||
  segment: "a" | "b" | "c" | "d" | "e" | "f" | "g" | "dp",
 | 
			
		||||
): boolean {
 | 
			
		||||
  return segmentStates.value[segment] || afterglowStates.value[segment];
 | 
			
		||||
  return segmentStates.value[segment] || afterglowBuffers.value[segment].some(state => state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 更新引脚状态的函数
 | 
			
		||||
@@ -170,17 +173,16 @@ function updateSegmentStates() {
 | 
			
		||||
    // 可扩展其他模式
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // 如果COM口激活,更新所有段的状态到存储槽
 | 
			
		||||
  if (comActive) {
 | 
			
		||||
    updateAfterglowBuffers();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (const pin of props.pins) {
 | 
			
		||||
    if (["a", "b", "c", "d", "e", "f", "g", "dp"].includes(pin.pinId)) {
 | 
			
		||||
      // 如果COM未激活,段直接进入熄灭(带余晖效果)
 | 
			
		||||
      if (!comActive) {
 | 
			
		||||
        handleSegmentStateChange(pin.pinId, false);
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // 如果constraint为空,则默认为未激活状态
 | 
			
		||||
      if (!pin.constraint) {
 | 
			
		||||
        handleSegmentStateChange(pin.pinId, false);
 | 
			
		||||
        segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = false;
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -193,63 +195,69 @@ function updateSegmentStates() {
 | 
			
		||||
        // 共阳极: 低电平激活段
 | 
			
		||||
        newState = pinState === "low";
 | 
			
		||||
      }
 | 
			
		||||
      handleSegmentStateChange(pin.pinId, newState);
 | 
			
		||||
      
 | 
			
		||||
      // 更新当前状态
 | 
			
		||||
      segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = newState && comActive;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 处理段状态变化
 | 
			
		||||
function handleSegmentStateChange(segmentId: string, newState: boolean) {
 | 
			
		||||
  const typedSegmentId = segmentId as keyof typeof segmentStates.value;
 | 
			
		||||
  const currentState = segmentStates.value[typedSegmentId];
 | 
			
		||||
  
 | 
			
		||||
  // 更新实际状态
 | 
			
		||||
  segmentStates.value[typedSegmentId] = newState;
 | 
			
		||||
  
 | 
			
		||||
  // 处理余晖效果
 | 
			
		||||
  if (currentState && !newState) {
 | 
			
		||||
    // 从激活变为非激活,启动余晖
 | 
			
		||||
    if (afterglowTimers.value[segmentId]) {
 | 
			
		||||
      window.clearTimeout(afterglowTimers.value[segmentId]);
 | 
			
		||||
// 更新余晖存储槽 - 将当前段状态添加到存储槽中
 | 
			
		||||
function updateAfterglowBuffers() {
 | 
			
		||||
  for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
 | 
			
		||||
    const typedSegmentId = segmentId as keyof typeof segmentStates.value;
 | 
			
		||||
    const currentState = segmentStates.value[typedSegmentId];
 | 
			
		||||
    
 | 
			
		||||
    // 将当前状态添加到存储槽的开头
 | 
			
		||||
    afterglowBuffers.value[segmentId].unshift(currentState);
 | 
			
		||||
    
 | 
			
		||||
    // 如果存储槽超过了最大容量,移除最旧的状态
 | 
			
		||||
    if (afterglowBuffers.value[segmentId].length > props.AFTERGLOW_BUFFER_SIZE) {
 | 
			
		||||
      afterglowBuffers.value[segmentId].pop();
 | 
			
		||||
    }
 | 
			
		||||
    afterglowStates.value[typedSegmentId] = true;
 | 
			
		||||
    afterglowTimers.value[segmentId] = window.setTimeout(() => {
 | 
			
		||||
      afterglowStates.value[typedSegmentId] = false;
 | 
			
		||||
      delete afterglowTimers.value[segmentId];
 | 
			
		||||
    }, props.AFTERGLOW_DURATION ?? 700);
 | 
			
		||||
  } else if (newState) {
 | 
			
		||||
    // 重新激活,清除余晖
 | 
			
		||||
    if (afterglowTimers.value[segmentId]) {
 | 
			
		||||
      window.clearTimeout(afterglowTimers.value[segmentId]);
 | 
			
		||||
      delete afterglowTimers.value[segmentId];
 | 
			
		||||
    }
 | 
			
		||||
    afterglowStates.value[typedSegmentId] = false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 开始余晖更新间隔
 | 
			
		||||
function startAfterglowUpdates() {
 | 
			
		||||
  if (updateIntervalTimer) return;
 | 
			
		||||
  
 | 
			
		||||
  updateIntervalTimer = window.setInterval(() => {
 | 
			
		||||
    updateSegmentStates();
 | 
			
		||||
  }, props.AFTERGLOW_UPDATE_INTERVAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 停止余晖更新间隔
 | 
			
		||||
function stopAfterglowUpdates() {
 | 
			
		||||
  if (updateIntervalTimer) {
 | 
			
		||||
    window.clearInterval(updateIntervalTimer);
 | 
			
		||||
    updateIntervalTimer = null;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 监听约束状态变化
 | 
			
		||||
function onConstraintChange(constraint: string, level: string) {
 | 
			
		||||
  const affectedPin = props.pins.find((pin) => pin.constraint === constraint);
 | 
			
		||||
  if (
 | 
			
		||||
    affectedPin &&
 | 
			
		||||
    ["a", "b", "c", "d", "e", "f", "g", "dp"].includes(affectedPin.pinId)
 | 
			
		||||
  ) {
 | 
			
		||||
  if (affectedPin) {
 | 
			
		||||
    updateSegmentStates();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 生命周期钩子
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  // 初始化余晖存储槽
 | 
			
		||||
  for (const segmentId of ["a", "b", "c", "d", "e", "f", "g", "dp"]) {
 | 
			
		||||
    afterglowBuffers.value[segmentId] = Array(props.AFTERGLOW_BUFFER_SIZE).fill(false);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  updateSegmentStates();
 | 
			
		||||
  onConstraintStateChange(onConstraintChange);
 | 
			
		||||
  startAfterglowUpdates();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onUnmounted(() => {
 | 
			
		||||
  // 清理约束状态监听
 | 
			
		||||
  // 清理所有余晖定时器
 | 
			
		||||
  Object.values(afterglowTimers.value).forEach(timerId => {
 | 
			
		||||
    if (timerId) window.clearTimeout(timerId);
 | 
			
		||||
  });
 | 
			
		||||
  stopAfterglowUpdates();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 暴露属性和方法
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user