feat: 添加多种动画效果,包括触摸反馈、涟漪、弹性缩放和滑入动画,优化用户交互体验
This commit is contained in:
@@ -121,3 +121,117 @@
|
|||||||
.animate-rotate-glow {
|
.animate-rotate-glow {
|
||||||
animation: rotate-glow 10s linear infinite;
|
animation: rotate-glow 10s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 移动端触摸反馈动画 */
|
||||||
|
@keyframes tap-feedback {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-tap {
|
||||||
|
animation: tap-feedback 0.2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 涟漪效果 */
|
||||||
|
@keyframes ripple {
|
||||||
|
0% {
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(4);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-ripple {
|
||||||
|
animation: ripple 0.6s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 弹性缩放动画 */
|
||||||
|
@keyframes bounce-scale {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-bounce-scale {
|
||||||
|
animation: bounce-scale 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滑入动画 - 从左 */
|
||||||
|
@keyframes slide-in-left {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-30px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-left {
|
||||||
|
animation: slide-in-left 0.4s ease-out forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 滑入动画 - 从右 */
|
||||||
|
@keyframes slide-in-right {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(30px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-slide-in-right {
|
||||||
|
animation: slide-in-right 0.4s ease-out forwards;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 脉冲缩放动画 */
|
||||||
|
@keyframes pulse-scale {
|
||||||
|
0%, 100% {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.02);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-pulse-scale {
|
||||||
|
animation: pulse-scale 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 隐藏滚动条 */
|
||||||
|
.scrollbar-hide {
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
scrollbar-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-hide::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 平滑滚动 */
|
||||||
|
.smooth-scroll {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|||||||
@@ -116,12 +116,14 @@ useHead({
|
|||||||
:label="locale === 'zh-CN' ? 'EN' : '中文'"
|
:label="locale === 'zh-CN' ? 'EN' : '中文'"
|
||||||
color="neutral"
|
color="neutral"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
class="transition-all duration-300 active:scale-90 touch-manipulation"
|
||||||
@click="toggleLanguage"
|
@click="toggleLanguage"
|
||||||
/>
|
/>
|
||||||
<UButton
|
<UButton
|
||||||
:icon="isDark ? 'i-heroicons-sun' : 'i-heroicons-moon'"
|
:icon="isDark ? 'i-heroicons-sun' : 'i-heroicons-moon'"
|
||||||
color="neutral"
|
color="neutral"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
|
class="transition-all duration-300 active:scale-90 active:rotate-180 touch-manipulation"
|
||||||
@click="colorMode.preference = isDark ? 'light' : 'dark'"
|
@click="colorMode.preference = isDark ? 'light' : 'dark'"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -146,13 +148,14 @@ useHead({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Categories -->
|
<!-- Categories -->
|
||||||
<div class="flex items-center gap-2 overflow-x-auto pb-2">
|
<div class="flex items-center gap-2 overflow-x-auto pb-2 scrollbar-hide">
|
||||||
<UButton
|
<UButton
|
||||||
v-for="category in categories"
|
v-for="category in categories"
|
||||||
:key="category.id"
|
:key="category.id"
|
||||||
:label="category.name[locale as 'zh-CN' | 'en-US']"
|
:label="category.name[locale as 'zh-CN' | 'en-US']"
|
||||||
:color="selectedCategory === category.id ? 'primary' : 'neutral'"
|
:color="selectedCategory === category.id ? 'primary' : 'neutral'"
|
||||||
:variant="selectedCategory === category.id ? 'solid' : 'ghost'"
|
:variant="selectedCategory === category.id ? 'solid' : 'ghost'"
|
||||||
|
class="transition-all duration-300 active:scale-90 touch-manipulation"
|
||||||
@click="selectedCategory = category.id"
|
@click="selectedCategory = category.id"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -170,7 +173,7 @@ useHead({
|
|||||||
<div class="absolute -inset-0.5 bg-gradient-to-r from-primary-500 via-purple-500 to-blue-500 rounded-2xl opacity-0 group-hover:opacity-100 blur transition-all duration-500 group-hover:blur-md"></div>
|
<div class="absolute -inset-0.5 bg-gradient-to-r from-primary-500 via-purple-500 to-blue-500 rounded-2xl opacity-0 group-hover:opacity-100 blur transition-all duration-500 group-hover:blur-md"></div>
|
||||||
|
|
||||||
<UCard
|
<UCard
|
||||||
class="cursor-pointer backdrop-blur-sm bg-white/90 dark:bg-gray-900/90 border border-gray-200/50 dark:border-gray-800/50 transition-all duration-500 hover:shadow-2xl hover:shadow-primary-500/20 hover:-translate-y-2 relative overflow-hidden"
|
class="cursor-pointer backdrop-blur-sm bg-white/90 dark:bg-gray-900/90 border border-gray-200/50 dark:border-gray-800/50 transition-all duration-500 hover:shadow-2xl hover:shadow-primary-500/20 hover:-translate-y-2 active:scale-95 active:shadow-lg relative overflow-hidden touch-manipulation"
|
||||||
@click="openAppDetail(app)"
|
@click="openAppDetail(app)"
|
||||||
>
|
>
|
||||||
<!-- 内部发光效果 -->
|
<!-- 内部发光效果 -->
|
||||||
@@ -178,9 +181,9 @@ useHead({
|
|||||||
|
|
||||||
<div class="flex items-start gap-4 relative z-10">
|
<div class="flex items-start gap-4 relative z-10">
|
||||||
<!-- App Icon -->
|
<!-- App Icon -->
|
||||||
<div class="size-16 rounded-2xl bg-gradient-to-br from-blue-500 to-blue-600 flex items-center justify-center text-white font-bold text-2xl shrink-0 shadow-lg shadow-blue-500/50 relative overflow-hidden group-hover:shadow-2xl group-hover:shadow-blue-500/60 transition-all duration-500 group-hover:scale-110 group-hover:rotate-3 p-2">
|
<div class="size-16 rounded-2xl bg-gradient-to-br from-blue-500 to-blue-600 flex items-center justify-center text-white font-bold text-2xl shrink-0 shadow-lg shadow-blue-500/50 relative overflow-hidden group-hover:shadow-2xl group-hover:shadow-blue-500/60 transition-all duration-500 group-hover:scale-110 group-hover:rotate-3 group-active:scale-105 group-active:rotate-1 p-2">
|
||||||
<div class="absolute inset-0 bg-gradient-to-tr from-white/0 via-white/30 to-white/0 translate-x-[-100%] group-hover:translate-x-[100%] transition-transform duration-700"></div>
|
<div class="absolute inset-0 bg-gradient-to-tr from-white/0 via-white/30 to-white/0 translate-x-[-100%] group-hover:translate-x-[100%] group-active:translate-x-[50%] transition-transform duration-700"></div>
|
||||||
<img :src="app.icon" :alt="app.name" class="size-full object-contain relative z-10 rounded-lg" />
|
<img :src="app.icon" :alt="app.name" class="size-full object-contain relative z-10 rounded-lg transition-transform duration-300 group-active:scale-95" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- App Info -->
|
<!-- App Info -->
|
||||||
@@ -207,7 +210,7 @@ useHead({
|
|||||||
label="iOS"
|
label="iOS"
|
||||||
size="sm"
|
size="sm"
|
||||||
block
|
block
|
||||||
class="transition-all duration-300 hover:shadow-lg hover:shadow-blue-500/50 hover:-translate-y-1"
|
class="transition-all duration-300 hover:shadow-lg hover:shadow-blue-500/50 hover:-translate-y-1 active:scale-95 active:shadow-md touch-manipulation"
|
||||||
@click.stop="handleDownload(app, 'ios')"
|
@click.stop="handleDownload(app, 'ios')"
|
||||||
/>
|
/>
|
||||||
<UButton
|
<UButton
|
||||||
@@ -216,7 +219,7 @@ useHead({
|
|||||||
label="Android"
|
label="Android"
|
||||||
size="sm"
|
size="sm"
|
||||||
block
|
block
|
||||||
class="transition-all duration-300 hover:shadow-lg hover:shadow-blue-500/50 hover:-translate-y-1"
|
class="transition-all duration-300 hover:shadow-lg hover:shadow-blue-500/50 hover:-translate-y-1 active:scale-95 active:shadow-md touch-manipulation"
|
||||||
@click.stop="handleDownload(app, 'android')"
|
@click.stop="handleDownload(app, 'android')"
|
||||||
/>
|
/>
|
||||||
<UButton
|
<UButton
|
||||||
@@ -225,7 +228,7 @@ useHead({
|
|||||||
label="Web"
|
label="Web"
|
||||||
size="sm"
|
size="sm"
|
||||||
block
|
block
|
||||||
class="transition-all duration-300 hover:shadow-lg hover:shadow-blue-500/50 hover:-translate-y-1"
|
class="transition-all duration-300 hover:shadow-lg hover:shadow-blue-500/50 hover:-translate-y-1 active:scale-95 active:shadow-md touch-manipulation"
|
||||||
@click.stop="handleDownload(app, 'h5')"
|
@click.stop="handleDownload(app, 'h5')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user