FPGA_WebLab/src/components/equipments/SMT_LED.vue

263 lines
5.9 KiB
Vue

<template>
<div class="led-container" :style="{ width: width + 'px', height: height + 'px', position: 'relative' }">
<svg
xmlns="http://www.w3.org/2000/svg"
:width="width"
:height="height"
viewBox="0 0 100 60"
class="smt-led"
>
<!-- LED 基座 -->
<rect width="100" height="60" x="0" y="0" fill="#333" rx="5" ry="5" />
<!-- LED 主体 -->
<rect width="90" height="50" x="5" y="5" fill="#222" rx="3" ry="3" />
<!-- LED 发光部分 -->
<rect
width="70"
height="30"
x="15"
y="15"
:fill="ledColor"
:style="{ opacity: isOn ? 1 : 0.2 }"
rx="15"
ry="15"
class="interactive"
/>
<!-- LED 光晕效果 -->
<rect
v-if="isOn"
width="76"
height="36"
x="12"
y="12"
:fill="ledColor"
:style="{ opacity: 0.3 }"
rx="18"
ry="18"
filter="blur(5px)"
class="glow"
/> </svg>
<!-- 渲染自定义引脚数组 -->
<div v-for="pin in props.pins" :key="pin.pinId"
:style="{
position: 'absolute',
left: `${pin.x * props.size}px`,
top: `${pin.y * props.size}px`,
transform: 'translate(-50%, -50%)'
}"
:data-pin-wrapper="`${pin.pinId}`"
:data-pin-x="`${pin.x * props.size}`"
:data-pin-y="`${pin.y * props.size}`">
<Pin
:ref="el => { if(el) pinRefs[pin.pinId] = el }"
:label="pin.pinId"
:constraint="pin.constraint"
:pinId="pin.pinId"
@pin-click="$emit('pin-click', $event)"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted } from 'vue';
import { useConstraintsStore } from '../../stores/constraints';
import Pin from './Pin.vue';
const {getConstraintState, onConstraintStateChange} = useConstraintsStore();
// 存储多个Pin引用
const pinRefs = ref<Record<string, any>>({});
// LED特有属性
interface LEDProps {
size?: number;
color?: string;
brightness?: number;
pins?: {
pinId: string;
constraint: string;
x: number;
y: number;
}[];
}
const props = withDefaults(defineProps<LEDProps>(), {
size: 1,
color: 'red',
brightness: 80,
pins: () => [
{
pinId: 'LED',
constraint: '',
x: 50,
y: 30
}
]
});
const width = computed(() => 100 * props.size);
const height = computed(() => 60 * props.size);
const isOn = ref(false);
const colorMap: Record<string, string> = {
'red': '#ff3333',
'green': '#33ff33',
'blue': '#3333ff',
'yellow': '#ffff33',
'orange': '#ff9933',
'white': '#ffffff',
'purple': '#9933ff'
};
const ledColor = computed(() => {
return colorMap[props.color.toLowerCase()] || props.color;
});
// 获取LED的constraint值
const ledConstraint = computed(() => {
if (props.pins && props.pins.length > 0) {
return props.pins[0].constraint;
}
return '';
});
// 监听约束状态变化
let unsubscribe: (() => void) | null = null;
onMounted(() => {
if (ledConstraint.value) {
unsubscribe = onConstraintStateChange((constraint, level) => {
if (constraint === ledConstraint.value) {
isOn.value = (level === 'high');
}
});
// 初始化LED状态
const currentState = getConstraintState(ledConstraint.value);
isOn.value = (currentState === 'high');
}
});
onUnmounted(() => {
if (unsubscribe) {
unsubscribe();
}
});
watch(() => ledConstraint.value, (newConstraint) => {
if (unsubscribe) {
unsubscribe();
unsubscribe = null;
}
if (newConstraint) {
unsubscribe = onConstraintStateChange((constraint, level) => {
if (constraint === newConstraint) {
isOn.value = (level === 'high');
}
});
// 初始化LED状态
const currentState = getConstraintState(newConstraint);
isOn.value = (currentState === 'high');
}
});
defineExpose({
getInfo: () => ({
color: props.color,
isOn: isOn.value,
constraint: ledConstraint.value,
direction: 'input',
type: 'digital',
pins: props.pins
}),
getPinPosition: (pinId: string) => {
// 如果是自定义的引脚ID
if (props.pins && props.pins.length > 0) {
console.log('SMT_LED查找Pin ID:', pinId);
console.log('SMT_LED组件尺寸:', props.size, '宽高:', width.value, 'x', height.value);
const customPin = props.pins.find(p => p.pinId === pinId);
console.log('找到的引脚配置:', customPin);
if (customPin) {
// 考虑组件尺寸的缩放
const scaledX = customPin.x * props.size;
const scaledY = customPin.y * props.size;
console.log('使用Pin缩放后的坐标:', scaledX, scaledY);
return {
x: scaledX,
y: scaledY
};
}
console.log('未找到匹配的引脚');
return null;
}
console.log('没有引脚配置');
return null;
}
});
</script>
<script lang="ts">
// 添加一个静态方法来获取默认props
export function getDefaultProps() {
return {
size: 1,
color: 'red',
brightness: 80,
pins: [
{
pinId: 'LED',
constraint: '',
x: 50,
y: 30
}
]
};
}
</script>
<style scoped>
.led-container {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.smt-led {
display: block;
padding: 0;
margin: 0;
line-height: 0;
font-size: 0;
box-sizing: content-box;
overflow: visible;
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.interactive {
cursor: pointer;
transition: all 0.2s ease-in-out;
}
.interactive:hover {
filter: brightness(1.2);
}
.glow {
pointer-events: none;
}
</style>