
14 changed files with 793 additions and 123 deletions
@ -0,0 +1 @@ |
|||
{"v":"5.12.2","fr":60,"ip":0,"op":55,"w":88,"h":88,"nm":"Frame 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"â½ Group 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[360]},{"t":55,"s":[720]}],"ix":10},"p":{"a":0,"k":[44.5,43.5,0],"ix":2,"l":2},"a":{"a":0,"k":[33.5,33.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":55,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Ellipse 2","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50.25,16.75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-18.502]],"o":[[18.502,0],[0,0]],"v":[[-16.75,-16.75],[16.75,16.75]],"c":false},"ix":2},"nm":"路徠1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.357,0.435,0.965],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"æÂÂè¾¹ 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Ã¥ÂÂæÂ¢"}],"nm":"Ellipse 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":55,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Ellipse 1","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33.5,33.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[67,67],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"æ¤ÂÃ¥ÂÂ路徠1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.898,0.91,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":7,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"æÂÂè¾¹ 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Ã¥ÂÂæÂ¢"}],"nm":"Ellipse 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":55,"st":0,"ct":1,"bm":0}],"markers":[],"props":{}} |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,175 @@ |
|||
<template> |
|||
<div class="svg-icon-wrapper" :style="wrapperStyle" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave"> |
|||
<div class="svg-icon" v-html="svgContent" :style="{ |
|||
'--icon-color': (hoverEffect || isActive) ? activeColor : defaultColor, |
|||
'--icon-hover-color': activeColor |
|||
}"></div> |
|||
<!-- :style="iconStyle" --> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'SvgIcon', |
|||
props: { |
|||
// 图标路径(必须) |
|||
iconPath: { |
|||
type: String, |
|||
required: true |
|||
}, |
|||
// 默认颜色 |
|||
defaultColor: { |
|||
type: String, |
|||
default: '#606266' |
|||
}, |
|||
// 激活颜色(传入后才允许变色) |
|||
activeColor: { |
|||
type: String, |
|||
default: null |
|||
}, |
|||
// 是否开启悬停变色 |
|||
hoverEffect: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
// 图标大小 |
|||
size: { |
|||
type: [String, Number], |
|||
default: '14px' |
|||
}, |
|||
// 是否当前激活状态 |
|||
isActive: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
svgContent: '', |
|||
isHovering: false, |
|||
currentColor: this.defaultColor |
|||
} |
|||
}, |
|||
computed: { |
|||
wrapperStyle() { |
|||
return { |
|||
width: typeof this.size === 'number' ? `${this.size}px` : this.size, |
|||
height: typeof this.size === 'number' ? `${this.size}px` : this.size, |
|||
display: 'inline-flex', |
|||
alignItems: 'center', |
|||
justifyContent: 'center' |
|||
} |
|||
}, |
|||
iconStyle() { |
|||
return { |
|||
width: '100%', |
|||
height: '100%', |
|||
color: this.currentColor, |
|||
transition: 'color 0.3s ease' |
|||
} |
|||
}, |
|||
shouldChangeColor() { |
|||
return this.activeColor && (this.hoverEffect || this.isActive) |
|||
} |
|||
}, |
|||
watch: { |
|||
isActive(newVal) { |
|||
console.log(newVal, 'newVal---'); |
|||
if (this.shouldChangeColor) { |
|||
this.currentColor = newVal ? this.activeColor : this.defaultColor |
|||
console.log(this.currentColor, 'this.currentColor--'); |
|||
} |
|||
}, |
|||
defaultColor(newVal) { |
|||
if (!this.isHovering && !this.isActive) { |
|||
this.currentColor = newVal |
|||
} |
|||
}, |
|||
activeColor() { |
|||
this.updateColorState() |
|||
} |
|||
}, |
|||
methods: { |
|||
async loadSvg() { |
|||
try { |
|||
const response = await fetch(this.iconPath) |
|||
this.svgContent = await response.text() |
|||
this.processSvg() |
|||
} catch (error) { |
|||
console.error('Failed to load SVG:', error) |
|||
} |
|||
}, |
|||
processSvg() { |
|||
// 确保SVG没有自带颜色,以便用CSS控制 |
|||
this.$nextTick(() => { |
|||
const svgElement = this.$el.querySelector('svg') |
|||
if (svgElement) { |
|||
// 更彻底地移除颜色属性 |
|||
svgElement.removeAttribute('fill') |
|||
svgElement.removeAttribute('style') |
|||
const paths = svgElement.querySelectorAll('path, circle, rect, polygon') |
|||
paths.forEach(el => { |
|||
el.removeAttribute('fill') |
|||
}) |
|||
svgElement.style.fill = 'currentColor' |
|||
svgElement.style.width = '100%' |
|||
svgElement.style.height = '100%' |
|||
} |
|||
}) |
|||
}, |
|||
handleMouseEnter() { |
|||
this.isHovering = true |
|||
this.updateColorState() |
|||
}, |
|||
handleMouseLeave() { |
|||
this.isHovering = false |
|||
this.updateColorState() |
|||
}, |
|||
updateColorState() { |
|||
if (this.activeColor) { |
|||
if (this.isActive) { |
|||
this.currentColor = this.activeColor |
|||
} else { |
|||
this.currentColor = this.isHovering && this.hoverEffect ? |
|||
this.activeColor : |
|||
this.defaultColor |
|||
} |
|||
} else { |
|||
this.currentColor = this.defaultColor |
|||
} |
|||
} |
|||
}, |
|||
created() { |
|||
this.loadSvg() |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.svg-icon-wrapper { |
|||
cursor: pointer; |
|||
} |
|||
|
|||
|
|||
.svg-icon { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
color: var(--icon-color); |
|||
transition: color 0.3s; |
|||
} |
|||
|
|||
.svg-icon:hover { |
|||
color: var(--icon-hover-color); |
|||
} |
|||
|
|||
.svg-icon { |
|||
display: inline-flex; |
|||
} |
|||
|
|||
.svg-icon>>>svg { |
|||
fill: currentColor; |
|||
} |
|||
</style> |
Loading…
Reference in new issue