|
|
@@ -1,12 +1,11 @@
|
|
|
<template>
|
|
|
- <div class="tank">
|
|
|
- <!-- 方形镂空罐体图标 -->
|
|
|
- <i class="icon iconfont-colour icon-tank3 tank_s" :style="getTankStyle">
|
|
|
- <div class="tank_title" v-if="title" :style="{ fontSize: titleFontSize }">
|
|
|
+ <!-- 方形镂空罐体 -->
|
|
|
+ <div class="tank_body">
|
|
|
+ <i class="icon iconfont-colour icon-tank3 tank_icon" :style="getTankStyle">
|
|
|
+ <div v-if="title" :style="titleStyle">
|
|
|
{{ title }}
|
|
|
</div>
|
|
|
</i>
|
|
|
-
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -18,68 +17,89 @@ const props = defineProps({
|
|
|
type: String,
|
|
|
required: true
|
|
|
},
|
|
|
- iconSize: {
|
|
|
+ iconSize: { // 图标大小
|
|
|
type: Number,
|
|
|
- default: 400
|
|
|
+ default: 200,
|
|
|
},
|
|
|
- iconWidth: {
|
|
|
+ iconWidth: { // 图标宽度
|
|
|
type: Number,
|
|
|
},
|
|
|
- iconHeight: {
|
|
|
+ iconHeight: { // 图标高度
|
|
|
type: Number,
|
|
|
},
|
|
|
})
|
|
|
|
|
|
-// 根据标题长度动态设置字体大小
|
|
|
-const titleFontSize = computed(() => {
|
|
|
- const len = props.title.length
|
|
|
- if (len <= 4) return '24px'
|
|
|
- if (len <= 8) return '16px'
|
|
|
- if (len <= 12) return '14px'
|
|
|
- return '12px'
|
|
|
+// 图标尺寸计算
|
|
|
+const iconSize = computed(() => {
|
|
|
+ // 判断是否同时传入了width和height
|
|
|
+ if (props.iconWidth !== null && props.iconHeight !== null) {
|
|
|
+ return Math.min(props.iconWidth, props.iconHeight);
|
|
|
+ }
|
|
|
+ // 没传入,使用默认的iconSize
|
|
|
+ return props.iconSize;
|
|
|
+});
|
|
|
+
|
|
|
+// 计算图标缩放比例
|
|
|
+const scaleInfo = computed(() => {
|
|
|
+ const scaleX = props.iconWidth ? props.iconWidth / iconSize.value : 1
|
|
|
+ const scaleY = props.iconHeight ? props.iconHeight / iconSize.value : 1
|
|
|
+ return { scaleX, scaleY }
|
|
|
})
|
|
|
|
|
|
-const fontSize = computed(() => props.iconSize ?? 200)
|
|
|
+// 罐子图标样式(包含缩放)
|
|
|
+const getTankStyle = computed(() => ({
|
|
|
+ fontSize: `${iconSize.value}px`,
|
|
|
+ display: 'inline-block',
|
|
|
+ transform: `scale(${scaleInfo.value.scaleX}, ${scaleInfo.value.scaleY})`
|
|
|
+}))
|
|
|
|
|
|
-// 罐子样式
|
|
|
-const getTankStyle = computed(() => {
|
|
|
- const style = {
|
|
|
- fontSize: fontSize.value + 'px',
|
|
|
- display: 'inline-block'
|
|
|
+// 标题样式(应用反向缩放抵消图标缩放影响,新增最小15px限制)
|
|
|
+const titleStyle = computed(() => {
|
|
|
+ const { scaleX, scaleY } = scaleInfo.value
|
|
|
+ // 计算标题基础字体大小(不受缩放影响)
|
|
|
+ const len = props.title.length
|
|
|
+ let baseSize;
|
|
|
+ if (len <= 4) {
|
|
|
+ baseSize = iconSize.value * 0.11;
|
|
|
+ } else if (len < 8) {
|
|
|
+ baseSize = iconSize.value * 0.08;
|
|
|
+ } else if (len < 12) {
|
|
|
+ baseSize = iconSize.value * 0.06;
|
|
|
+ } else {
|
|
|
+ baseSize = iconSize.value * 0.04;
|
|
|
}
|
|
|
- const scaleX = props.iconWidth ? props.iconWidth / fontSize.value : 1
|
|
|
- const scaleY = props.iconHeight ? props.iconHeight / fontSize.value : 1
|
|
|
+ // 限制最大30px,最小15px
|
|
|
+ const maxSize = 30;
|
|
|
+ const minSize = 15;
|
|
|
+ const finalSize = Math.min(Math.max(baseSize, minSize), maxSize); // 先取最小限制,再取最大限制
|
|
|
|
|
|
- if (scaleX !== 1 || scaleY !== 1) {
|
|
|
- style.transform = `scale(${scaleX}, ${scaleY})`
|
|
|
- style['--scale-x'] = scaleX
|
|
|
- style['--scale-y'] = scaleY
|
|
|
+ return {
|
|
|
+ fontSize: `${finalSize}px`,
|
|
|
+ position: 'absolute',
|
|
|
+ top: '9%', // 保持在图标内顶部9%的位置
|
|
|
+ left: '50%',
|
|
|
+ // 核心:通过反向缩放抵消图标的缩放(1/scaleX 抵消 scaleX)
|
|
|
+ transform: `translate(-50%, -50%) scale(${1 / scaleX}, ${1 / scaleY})`,
|
|
|
+ color: '#e65100',
|
|
|
+ fontWeight: 'bold',
|
|
|
+ zIndex: 20,
|
|
|
+ pointerEvents: 'none',
|
|
|
+ textAlign: 'center',
|
|
|
+ //不换行
|
|
|
+ whiteSpace: 'nowrap'
|
|
|
}
|
|
|
-
|
|
|
- return style
|
|
|
-})
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
-<style lang="scss" scoped>
|
|
|
-.tank {
|
|
|
+<style scoped lang="scss">
|
|
|
+.tank_body {
|
|
|
+ text-align: center;
|
|
|
position: relative;
|
|
|
z-index: 10;
|
|
|
|
|
|
- .tank_s {
|
|
|
- position: relative;
|
|
|
+ .tank_icon {
|
|
|
+ position: relative; // 作为标题的定位容器
|
|
|
z-index: 10;
|
|
|
-
|
|
|
- .tank_title {
|
|
|
- position: absolute;
|
|
|
- top: 6%;
|
|
|
- left: 50%;
|
|
|
- transform: translate(-50%, -50%) scale(calc(1 / var(--scale-x, 1)), calc(1 / var(--scale-y, 1)));
|
|
|
- color: #e65100;
|
|
|
- font-weight: bold;
|
|
|
- z-index: 20;
|
|
|
- pointer-events: none;
|
|
|
- text-align: center;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|