he wei
2025-04-23 b9bd29a1a81f6f7de479e3cc3fdfe3d85fc660bf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<script setup>
import { ref, computed } from "vue";
const props = defineProps({
  label: {
    type: String,
    required: true
  },
  unit: {
    type: String,
    default: '',
  },
  value: {
    type: [String, Number],
    required: true
  },
  color: {
    type: String,
    default: '#0ff'
  },
})
 
function hexToRgba(hex, alpha = 1) {
  // 去除 # 符号
  hex = hex.replace('#', '');
 
  // 处理 3 位和 6 位十六进制颜色码
  if (hex.length === 3) {
    hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
  }
 
  // 解析红、绿、蓝通道的值
  const r = parseInt(hex.slice(0, 2), 16);
  const g = parseInt(hex.slice(2, 4), 16);
  const b = parseInt(hex.slice(4, 6), 16);
 
  // 生成 rgba 字符串
  return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
 
const bgColor = computed(() => {
  return hexToRgba(props.color, 0.2);
});
 
const bdColor = computed(() => {
  return hexToRgba(props.color, 0.4);
});
 
 
 
</script>
 
<template>
  <div class="panel" :style="{ '--color': props.color, '--bg': bgColor, '--border-color': bdColor, '--bg2': '#052C3B'}">
    <div class="top">
      <div class="label">{{ label }}</div>
      <div class="unit" v-if="unit">{{ unit }}</div>
    </div>
    <div class="value">{{ value }}</div>
  </div>
</template>
 
<style scoped lang="less">
.panel {
  display: flex;
  flex-direction: column;
  justify-content: center;
  // align-items: center;
  padding: 6px 20px;
  height: 70px;
  width: 130px;
  color: var(--color);
  font-size: 14px;
  border: 2px solid var(--border-color);
  
  background-color: var(--bg) ;
  position: relative;
  .top {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    padding: 0 6px;
  }
  .unit {
    color: #fff;
    font-size: 12px;
  }
  .label {
 
  }
  .value {
    border: 2px solid var(--border-color);
    background: var(--bg2);
    font-weight: bold;
    width: 100%;
    font-size: 18px;
    padding: 6px;
    margin-top: 6px;
    // margin-left: 1em;
  }
  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: var(--color);
    mask: url("data:image/svg+xml,%3csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 30 30'%3e%3cpath d='M0 30L0 13L13 0L30 0' stroke='red' fill='none' stroke-width='4'%3e%3c/path%3e%3c/svg%3e") 4px 4px / auto 16% no-repeat,
    url("data:image/svg+xml,%3csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 30 30' transform='rotate(90)' %3e%3cpath d='M0 30L0 13L13 0L30 0' stroke='red' fill='none' stroke-width='4'%3e%3c/path%3e%3c/svg%3e") calc(100% - 4px) 4px e('/') auto 16% no-repeat,
    url("data:image/svg+xml,%3csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 30 30' transform='rotate(180)' %3e%3cpath d='M0 30L0 13L13 0L30 0' stroke='red' fill='none' stroke-width='4'%3e%3c/path%3e%3c/svg%3e") calc(100% - 4px) calc(100% - 4px) e('/') auto 16% no-repeat,
    url("data:image/svg+xml,%3csvg width='30' height='30' xmlns='http://www.w3.org/2000/svg' viewBox='-2 -2 30 30' transform='rotate(270)' %3e%3cpath d='M0 30L0 13L13 0L30 0' stroke='red' fill='none' stroke-width='4'%3e%3c/path%3e%3c/svg%3e") 4px calc(100% - 4px) e('/') auto 16% no-repeat;
    mask-composite: add;
  }
 
}
</style>