diff --git a/packages/distribute/assets/css/animations.css b/packages/distribute/assets/css/animations.css index d76b8fe..a36388f 100644 --- a/packages/distribute/assets/css/animations.css +++ b/packages/distribute/assets/css/animations.css @@ -235,3 +235,182 @@ scroll-behavior: smooth; -webkit-overflow-scrolling: touch; } + +/* 涟漪扩散动画 */ +@keyframes ripple-expand { + 0% { + transform: translate(-50%, -50%) scale(0); + opacity: 1; + } + 100% { + transform: translate(-50%, -50%) scale(40); + opacity: 0; + } +} + +/* 微妙的悬浮动画 */ +@keyframes float-subtle { + 0%, 100% { + transform: translateY(0) translateZ(0); + } + 50% { + transform: translateY(-5px) translateZ(10px); + } +} + +.animate-float-subtle { + animation: float-subtle 3s ease-in-out infinite; +} + +/* 脉冲光环动画 */ +@keyframes pulse-ring { + 0% { + transform: scale(0.95); + opacity: 1; + } + 50% { + transform: scale(1.05); + opacity: 0.8; + } + 100% { + transform: scale(0.95); + opacity: 1; + } +} + +.animate-pulse-ring { + animation: pulse-ring 2s ease-in-out infinite; +} + +/* 发光脉冲动画 */ +@keyframes pulse-glow { + 0%, 100% { + opacity: 0.5; + } + 50% { + opacity: 1; + } +} + +.animate-pulse-glow { + animation: pulse-glow 1.5s ease-in-out infinite; +} + +/* 微妙的脉冲动画 */ +@keyframes pulse-subtle { + 0%, 100% { + opacity: 1; + } + 50% { + opacity: 0.8; + } +} + +.animate-pulse-subtle { + animation: pulse-subtle 2s ease-in-out infinite; +} + +/* 微妙的滑入动画 */ +@keyframes slide-in-subtle { + from { + opacity: 0; + transform: translateX(10px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +.animate-slide-in-subtle { + animation: slide-in-subtle 0.5s ease-out; +} + +/* 3D透视 */ +.perspective-1000 { + perspective: 1000px; +} + +.transform-style-3d { + transform-style: preserve-3d; +} + +.transform-gpu { + transform: translateZ(0); + backface-visibility: hidden; + will-change: transform; +} + +/* 3D旋转效果 */ +.hover\:rotate-y-2:hover { + transform: translateY(-0.5rem) rotateY(2deg) translateZ(20px); +} + +/* 按钮闪光效果 */ +@keyframes button-shine { + 0% { + left: -100%; + } + 100% { + left: 100%; + } +} + +.animate-button-shine { + animation: button-shine 2s ease-in-out infinite; +} + +/* 震动效果 */ +@keyframes shake { + 0%, 100% { + transform: translateX(0); + } + 25% { + transform: translateX(-5px); + } + 75% { + transform: translateX(5px); + } +} + +.animate-shake { + animation: shake 0.5s ease-in-out; +} + +/* 弹跳效果 */ +@keyframes bounce-in { + 0% { + opacity: 0; + transform: scale(0.3) translateY(50px); + } + 50% { + transform: scale(1.05) translateY(-10px); + } + 70% { + transform: scale(0.9) translateY(0); + } + 100% { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +.animate-bounce-in { + animation: bounce-in 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55); +} + +/* 呼吸灯效果 */ +@keyframes breathe { + 0%, 100% { + opacity: 0.6; + transform: scale(1); + } + 50% { + opacity: 1; + transform: scale(1.1); + } +} + +.animate-breathe { + animation: breathe 2s ease-in-out infinite; +} diff --git a/packages/distribute/pages/index.vue b/packages/distribute/pages/index.vue index 799a390..9cc5eea 100644 --- a/packages/distribute/pages/index.vue +++ b/packages/distribute/pages/index.vue @@ -46,8 +46,42 @@ function openAppDetail(app: AppInfo) { navigateTo(`/apps/${app.id}`) } +// 创建涟漪效果 +function createRipple(event: MouseEvent | TouchEvent) { + const button = event.currentTarget as HTMLElement + const ripple = document.createElement('span') + const rect = button.getBoundingClientRect() + + const x = ('touches' in event ? event.touches[0]!.clientX : event.clientX) - rect.left + const y = ('touches' in event ? event.touches[0]!.clientY : event.clientY) - rect.top + + ripple.style.cssText = ` + position: absolute; + left: ${x}px; + top: ${y}px; + width: 10px; + height: 10px; + border-radius: 50%; + background: rgba(255, 255, 255, 0.6); + transform: translate(-50%, -50%) scale(0); + animation: ripple-expand 0.6s ease-out; + pointer-events: none; + z-index: 100; + ` + + button.style.position = 'relative' + button.style.overflow = 'hidden' + button.appendChild(ripple) + + setTimeout(() => ripple.remove(), 600) +} + // 下载处理 -async function handleDownload(app: AppInfo, type: 'ios' | 'android' | 'h5') { +async function handleDownload(app: AppInfo, type: 'ios' | 'android' | 'h5', event?: MouseEvent | TouchEvent) { + if (event) { + createRipple(event) + } + const url = app.downloads[type] if (!url) { @@ -87,14 +121,17 @@ useHead({