feat: remake most of forntend
This commit is contained in:
193
src/components/equipments/SMT_LED.vue
Normal file
193
src/components/equipments/SMT_LED.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<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 ? brightness/100 : 0.2 }"
|
||||
rx="15"
|
||||
ry="15"
|
||||
@click="toggleLed"
|
||||
class="interactive"
|
||||
/>
|
||||
|
||||
<!-- LED 光晕效果 -->
|
||||
<rect
|
||||
v-if="isOn"
|
||||
width="76"
|
||||
height="36"
|
||||
x="12"
|
||||
y="12"
|
||||
:fill="ledColor"
|
||||
:style="{ opacity: brightness/100 * 0.3 }"
|
||||
rx="18"
|
||||
ry="18"
|
||||
filter="blur(5px)"
|
||||
class="glow"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue';
|
||||
|
||||
// LED特有属性
|
||||
interface Props {
|
||||
size?: number;
|
||||
color?: string;
|
||||
initialOn?: boolean;
|
||||
brightness?: number;
|
||||
constraint?: string;
|
||||
}
|
||||
|
||||
// 组件属性定义
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
size: 1,
|
||||
color: 'red',
|
||||
initialOn: false,
|
||||
brightness: 80, // 亮度默认为80%
|
||||
constraint: ''
|
||||
});
|
||||
|
||||
// 计算实际宽高
|
||||
const width = computed(() => 100 * props.size);
|
||||
const height = computed(() => 60 * props.size);
|
||||
|
||||
// 内部状态
|
||||
const isOn = ref(props.initialOn);
|
||||
const brightness = ref(props.brightness);
|
||||
|
||||
// LED 颜色映射表
|
||||
const colorMap: Record<string, string> = {
|
||||
'red': '#ff3333',
|
||||
'green': '#33ff33',
|
||||
'blue': '#3333ff',
|
||||
'yellow': '#ffff33',
|
||||
'orange': '#ff9933',
|
||||
'white': '#ffffff',
|
||||
'purple': '#9933ff'
|
||||
};
|
||||
|
||||
// 计算实际LED颜色
|
||||
const ledColor = computed(() => {
|
||||
return colorMap[props.color.toLowerCase()] || props.color;
|
||||
});
|
||||
|
||||
// 定义组件发出的事件
|
||||
const emit = defineEmits([
|
||||
'toggle',
|
||||
'brightness-change',
|
||||
'value-change'
|
||||
]);
|
||||
|
||||
// 手动切换LED状态
|
||||
function toggleLed() {
|
||||
isOn.value = !isOn.value;
|
||||
emit('toggle', isOn.value);
|
||||
emit('value-change', {
|
||||
isOn: isOn.value,
|
||||
brightness: brightness.value
|
||||
});
|
||||
}
|
||||
|
||||
// 设置亮度
|
||||
function setBrightness(value: number) {
|
||||
// 限制亮度值在0-100范围内
|
||||
brightness.value = Math.max(0, Math.min(100, value));
|
||||
emit('brightness-change', brightness.value);
|
||||
emit('value-change', {
|
||||
isOn: isOn.value,
|
||||
brightness: brightness.value
|
||||
});
|
||||
}
|
||||
|
||||
// 手动设置LED开关状态
|
||||
function setLedState(on: boolean) {
|
||||
isOn.value = on;
|
||||
emit('toggle', isOn.value);
|
||||
emit('value-change', {
|
||||
isOn: isOn.value,
|
||||
brightness: brightness.value
|
||||
});
|
||||
}
|
||||
|
||||
// 监听props变化
|
||||
watch(() => props.brightness, (newVal) => {
|
||||
brightness.value = newVal;
|
||||
});
|
||||
|
||||
watch(() => props.initialOn, (newVal) => {
|
||||
isOn.value = newVal;
|
||||
});
|
||||
|
||||
// 向外暴露方法
|
||||
defineExpose({
|
||||
toggleLed,
|
||||
setBrightness,
|
||||
setLedState,
|
||||
getInfo: () => ({
|
||||
// LED特有属性
|
||||
color: props.color,
|
||||
isOn: isOn.value,
|
||||
brightness: brightness.value,
|
||||
constraint: props.constraint
|
||||
})
|
||||
});
|
||||
</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>
|
||||
Reference in New Issue
Block a user