This commit is contained in:
oneao committed 2025-08-27 17:32:01 +08:00
1 parent 4012be621b
commit 8680dc83cc
1 file changed
+45 -50
+45 -50
View File
@@ -11,28 +11,28 @@ export default {
return return
const rect = el.getBoundingClientRect() const rect = el.getBoundingClientRect()
const size = Math.max(rect.width, rect.height) * 2 const size = Math.max(rect.width, rect.height)
const flash = document.createElement('span') const ripple = document.createElement('span')
flash.style.position = 'absolute' ripple.style.position = 'absolute'
flash.style.width = flash.style.height = `${size}px` ripple.style.width = ripple.style.height = `${size}px`
flash.style.left = `${(rect.width - size) / 2}px` ripple.style.left = `${e.offsetX - size / 2}px`
flash.style.top = `${(rect.height - size) / 2}px` ripple.style.top = `${e.offsetY - size / 2}px`
flash.style.background = 'rgba(255,255,255,0.2)' ripple.style.background = 'rgba(255,255,255,0.4)' // 柔和水波纹
flash.style.borderRadius = '50%' ripple.style.borderRadius = '50%'
flash.style.pointerEvents = 'none' ripple.style.pointerEvents = 'none'
flash.style.transform = 'scale(0)' ripple.style.transform = 'scale(0)'
flash.style.opacity = '0.4' ripple.style.opacity = '0.6'
flash.style.transition = 'transform 0.3s ease-out, opacity 0.3s ease-out' ripple.style.transition = 'transform 0.4s, opacity 0.6s'
el.appendChild(flash) el.appendChild(ripple)
requestAnimationFrame(() => { setTimeout(() => {
flash.style.transform = 'scale(1)' ripple.style.transform = 'scale(2)'
flash.style.opacity = '0' ripple.style.opacity = '0'
}) }, 10)
flash.addEventListener('transitionend', () => flash.remove()) setTimeout(() => ripple.remove(), 600)
}) })
}, },
}, },
@@ -42,7 +42,7 @@ export default {
<template> <template>
<div class="button-demo"> <div class="button-demo">
<h3>现代后台按钮 - 瞬态扩散 + 内凹反馈</h3> <h3>现代后台按钮 - 内凹 + 柔和水波纹</h3>
<button v-flash class="btn btn-primary"> <button v-flash class="btn btn-primary">
主按钮 主按钮
</button> </button>
@@ -70,7 +70,6 @@ export default {
background: #f0f2f5; background: #f0f2f5;
} }
/* 基础按钮 */
.btn { .btn {
position: relative; position: relative;
display: inline-flex; display: inline-flex;
@@ -86,59 +85,55 @@ export default {
user-select: none; user-select: none;
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden; overflow: hidden;
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
&:focus-visible {
box-shadow: 0 0 0 3px rgba(0, 100, 250, 0.15);
}
&:hover:not(:disabled) {
filter: brightness(1.08);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
&:active:not(:disabled) {
filter: brightness(0.95);
box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.15);
}
} }
/* 主按钮 */ .btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.btn:focus-visible {
box-shadow: 0 0 0 3px rgba(0, 100, 250, 0.15);
}
.btn:hover:not(:disabled) {
filter: brightness(1.05);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}
.btn:active:not(:disabled) {
filter: brightness(0.95);
box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.1);
}
.btn-primary { .btn-primary {
background: linear-gradient(180deg, #0072ff, #0053d6); background: linear-gradient(180deg, #0072ff, #0053d6);
color: #fff; color: #fff;
} }
/* 次按钮 */
.btn-secondary { .btn-secondary {
background: #fff; background: #fff;
border: 1px solid #d9d9d9; border: 1px solid #d9d9d9;
color: #0064fa; color: #0064fa;
} }
/* 危险按钮 */
.btn-danger { .btn-danger {
background: linear-gradient(180deg, #ef4444, #b91c1c); background: linear-gradient(180deg, #ef4444, #b91c1c);
color: #fff; color: #fff;
} }
/* 链接按钮 */
.btn-link { .btn-link {
background: transparent; background: transparent;
color: #0064fa; color: #0064fa;
padding: 8px 16px; padding: 8px 16px;
}
&:hover:not(:disabled) { .btn-link:hover:not(:disabled) {
text-decoration: underline; text-decoration: underline;
background: rgba(0, 100, 250, 0.05); background: rgba(0, 100, 250, 0.05);
} }
&:active:not(:disabled) { .btn-link:active:not(:disabled) {
background: rgba(0, 100, 250, 0.1); background: rgba(0, 100, 250, 0.1);
}
} }
</style> </style>