feat: 更新图标组件的切换动画,增加轻量缩放和模糊过渡效果

This commit is contained in:
Hooray
2026-04-16 04:05:30 +08:00
parent d0029c019f
commit 68ffded498
2 changed files with 46 additions and 19 deletions
+1 -1
View File
@@ -123,7 +123,7 @@ const isActive = ref(false)
1. **图标尺寸**:图标默认尺寸为 `1em`,可通过父元素的 `font-size` 或图标的 `class` 控制
2. **图标颜色**:使用 `currentColor`,继承父元素的文字颜色
3. **加载状态**:使用图片 URL 时,加载失败会显示破损图片图标
4. **切换动画**:默认图标切换时无动画,可通过 `transition` prop 开启翻转动画(0.2s)
4. **切换动画**:默认图标切换时无动画,可通过 `transition` prop 开启轻量的缩放 + blur 过渡动画(0.24s)
## 典型使用场景
+45 -18
View File
@@ -15,15 +15,6 @@ const props = defineProps<{
class?: HTMLAttributes['class']
}>()
const IconWrapper = defineComponent({
render() {
const content = this.$slots.default?.()
return props.transition
? h(Transition, { name: 'icon-flip' }, () => content)
: content
},
})
const outputType = computed(() => {
if (!props.name) {
return
@@ -44,6 +35,20 @@ const outputType = computed(() => {
return 'svg'
}
})
const iconKey = computed(() => `${outputType.value ?? 'empty'}-${props.name}`)
const IconWrapper = defineComponent({
render() {
const content = this.$slots.default?.()
return props.transition
? h(Transition, { name: 'icon-switch' }, () => h('span', {
key: iconKey.value,
class: 'icon-switch-layer',
}, content))
: content
},
})
</script>
<template>
@@ -71,21 +76,43 @@ const outputType = computed(() => {
</template>
<style scoped>
.icon-flip-enter-active {
transition: all 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
.icon-switch-layer {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.icon-flip-leave-active {
transition: all 0.2s cubic-bezier(0.36, 0, 0.66, -0.56);
.icon-switch-enter-active,
.icon-switch-leave-active {
transform-origin: center;
backface-visibility: hidden;
transition:
opacity 0.2s,
transform 0.2s,
filter 0.2s;
will-change: opacity, transform, filter;
}
.icon-flip-enter-from {
.icon-switch-enter-from,
.icon-switch-leave-to {
opacity: 0;
transform: scale(0.5) rotate(90deg);
filter: blur(4px);
}
.icon-flip-leave-to {
opacity: 0;
transform: scale(0.5) rotate(-90deg);
.icon-switch-enter-from {
transform: scale(0.6);
}
.icon-switch-leave-to {
transform: scale(0.6);
}
.icon-switch-enter-to,
.icon-switch-leave-from {
opacity: 1;
filter: blur(0);
transform: scale(1);
}
</style>