add: segment afterglow effect

This commit is contained in:
alivender 2025-05-19 23:08:22 +08:00
parent 7f37514dfa
commit 8f2f90ef1d
1 changed files with 73 additions and 9 deletions

View File

@ -78,6 +78,7 @@ const pinRefs = ref<Record<string, any>>({});
interface SevenSegmentDisplayProps { interface SevenSegmentDisplayProps {
size?: number; size?: number;
color?: string; color?: string;
AFTERGLOW_DURATION?: number; //
pins?: { pins?: {
pinId: string; pinId: string;
constraint: string; constraint: string;
@ -133,37 +134,96 @@ const segmentStates = ref({
dp: false, dp: false,
}); });
//
const afterglowStates = ref({
a: false,
b: false,
c: false,
d: false,
e: false,
f: false,
g: false,
dp: false,
});
//
const afterglowTimers = ref<Record<string, number>>({});
// //
function isSegmentActive( function isSegmentActive(
segment: "a" | "b" | "c" | "d" | "e" | "f" | "g" | "dp", segment: "a" | "b" | "c" | "d" | "e" | "f" | "g" | "dp",
): boolean { ): boolean {
return segmentStates.value[segment]; return segmentStates.value[segment] || afterglowStates.value[segment];
} }
// //
function updateSegmentStates() { function updateSegmentStates() {
// COM
const comPin = props.pins.find(p => p.pinId === "COM");
let comActive = true;
if (comPin && comPin.constraint) {
const comState = getConstraintState(comPin.constraint);
if (props.cathodeType === "anode") {
// anodeCOM
comActive = comState !== "high";
}
//
}
for (const pin of props.pins) { for (const pin of props.pins) {
if (["a", "b", "c", "d", "e", "f", "g", "dp"].includes(pin.pinId)) { if (["a", "b", "c", "d", "e", "f", "g", "dp"].includes(pin.pinId)) {
// COM
if (!comActive) {
handleSegmentStateChange(pin.pinId, false);
continue;
}
// constraint // constraint
if (!pin.constraint) { if (!pin.constraint) {
segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = handleSegmentStateChange(pin.pinId, false);
false;
continue; continue;
} }
const pinState = getConstraintState(pin.constraint); const pinState = getConstraintState(pin.constraint);
let newState: boolean;
// /
if (props.cathodeType === "common") { if (props.cathodeType === "common") {
// : // :
segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = newState = pinState === "high";
pinState === "high";
} else { } else {
// : // :
segmentStates.value[pin.pinId as keyof typeof segmentStates.value] = newState = pinState === "low";
pinState === "low"; }
handleSegmentStateChange(pin.pinId, newState);
} }
} }
}
//
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]);
}
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;
} }
} }
@ -186,6 +246,10 @@ onMounted(() => {
onUnmounted(() => { onUnmounted(() => {
// //
//
Object.values(afterglowTimers.value).forEach(timerId => {
if (timerId) window.clearTimeout(timerId);
});
}); });
// //