fix: update dependencies and improve animation transitions

- Updated @types/react to version 19.2.7 in package.json and package-lock.json.
- Refined animation transitions in EnhancedButton, EnhancedInput, LoadingStates, Navbar, PageTransition, SkinCard, SkinDetailModal, and SkinViewer components by removing unnecessary ease properties for smoother animations.
- Added size prop to EnhancedInput for better customization.
- Enhanced SkinDetailModal and SkinCard styles for improved UI consistency.
This commit is contained in:
lafay
2026-01-09 17:44:21 +08:00
parent f5e4c2a04b
commit a7dd3a4bc0
11 changed files with 409 additions and 94 deletions

View File

@@ -109,8 +109,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
y: 0,
transition: {
duration: 0.5,
ease: [0.25, 0.46, 0.45, 0.94],
type: "spring",
type: "spring" as const,
stiffness: 100,
damping: 15
}
@@ -121,8 +120,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
rotateX: 15,
y: 50,
transition: {
duration: 0.3,
ease: "easeIn"
duration: 0.3
}
},
minimized: {
@@ -132,8 +130,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
width: 280,
height: 150,
transition: {
duration: 0.4,
ease: "easeInOut"
duration: 0.4
}
}
});
@@ -145,7 +142,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
opacity: 1,
transition: {
duration: 0.2,
type: "spring",
type: "spring" as const,
stiffness: 300,
damping: 20
}
@@ -162,7 +159,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
scale: 1.02,
transition: {
duration: 0.2,
type: "spring",
type: "spring" as const,
stiffness: 400,
damping: 25
}
@@ -195,14 +192,14 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
animate={isMinimized ? "minimized" : "animate"}
exit="exit"
transition={{ type: "spring", damping: 20, stiffness: 300 }}
className={`relative bg-white/95 dark:bg-gray-800/95 rounded-2xl shadow-2xl overflow-hidden border border-white/20 dark:border-gray-700/50 backdrop-blur-lg ${
className={`relative bg-white/98 dark:bg-gray-800/98 rounded-2xl shadow-2xl overflow-hidden border border-white/40 dark:border-gray-700/60 backdrop-blur-2xl ${
isMinimized ? 'fixed bottom-4 right-4' : 'w-full max-w-6xl h-[90vh]'
}`}
onClick={(e) => e.stopPropagation()}
>
{/* Header */}
<motion.div
className="absolute top-0 left-0 right-0 bg-gradient-to-r from-white/90 to-orange-50/90 dark:from-gray-800/90 dark:to-gray-700/90 backdrop-blur-md border-b border-orange-200/50 dark:border-gray-600/50 p-4 z-10"
className="absolute top-0 left-0 right-0 bg-gradient-to-r from-white/95 via-orange-50/95 to-amber-50/95 dark:from-gray-800/95 dark:via-gray-800/95 dark:to-gray-700/95 backdrop-blur-xl border-b border-orange-200/60 dark:border-gray-600/60 p-4 z-10 shadow-lg"
initial={{ y: -100 }}
animate={{ y: 0 }}
transition={{ delay: 0.2, duration: 0.4 }}
@@ -210,7 +207,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
<div className="flex items-center justify-between">
<div className="flex items-center space-x-4">
<motion.h2
className="text-2xl font-bold bg-gradient-to-r from-orange-500 to-amber-500 bg-clip-text text-transparent"
className="text-3xl font-bold bg-gradient-to-r from-orange-500 via-amber-500 to-yellow-500 bg-clip-text text-transparent drop-shadow-sm"
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.3 }}
@@ -219,10 +216,10 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
</motion.h2>
<div className="flex items-center space-x-2">
<motion.span
className={`px-3 py-1 text-sm rounded-full font-medium ${
className={`px-4 py-2 text-sm rounded-full font-semibold shadow-md ${
texture.type === 'SKIN'
? 'bg-gradient-to-r from-orange-100 to-amber-100 text-orange-800 dark:from-orange-900/30 dark:to-amber-900/30 dark:text-orange-300'
: 'bg-gradient-to-r from-purple-100 to-pink-100 text-purple-800 dark:from-purple-900/30 dark:to-pink-900/30 dark:text-purple-300'
? 'bg-gradient-to-r from-orange-100 to-amber-100 text-orange-800 dark:from-orange-900/40 dark:to-amber-900/40 dark:text-orange-300 border border-orange-200/50 dark:border-orange-700/30'
: 'bg-gradient-to-r from-purple-100 to-pink-100 text-purple-800 dark:from-purple-900/40 dark:to-pink-900/40 dark:text-purple-300 border border-purple-200/50 dark:border-purple-700/30'
}`}
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
@@ -231,12 +228,12 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
{texture.type === 'SKIN' ? '皮肤' : '披风'}
</motion.span>
{texture.is_slim && (
<motion.span
className="px-3 py-1 bg-gradient-to-r from-pink-100 to-rose-100 text-pink-800 dark:from-pink-900/30 dark:to-rose-900/30 text-sm rounded-full font-medium"
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ delay: 0.5, type: "spring", stiffness: 200 }}
>
<motion.span
className="px-4 py-2 bg-gradient-to-r from-pink-100 to-rose-100 text-pink-800 dark:from-pink-900/40 dark:to-rose-900/40 text-sm rounded-full font-semibold shadow-md border border-pink-200/50 dark:border-pink-700/30"
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ delay: 0.5, type: "spring", stiffness: 200 }}
>
</motion.span>
)}
@@ -259,9 +256,9 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
</motion.button>
<motion.button
onClick={onClose}
className="p-2 text-gray-500 hover:text-orange-500 dark:text-gray-400 dark:hover:text-orange-400 rounded-full hover:bg-orange-100 dark:hover:bg-orange-900/20 transition-all duration-200"
whileHover={{ scale: 1.1, rotate: 90 }}
whileTap={{ scale: 0.9 }}
className="p-3 text-gray-500 hover:text-red-500 dark:text-gray-400 dark:hover:text-red-400 rounded-full hover:bg-red-100 dark:hover:bg-red-900/30 transition-all duration-300 shadow-md hover:shadow-lg"
whileHover={{ scale: 1.15, rotate: 90 }}
whileTap={{ scale: 0.85 }}
initial={{ opacity: 0, rotate: -180 }}
animate={{ opacity: 1, rotate: 0 }}
transition={{ delay: 0.7 }}
@@ -276,7 +273,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
<div className="flex h-full pt-20">
{/* 3D 预览区域 */}
<motion.div
className="flex-1 flex items-center justify-center p-8 bg-gradient-to-br from-orange-50/30 to-amber-50/30 dark:from-gray-900/30 dark:to-gray-800/30"
className="flex-1 flex items-center justify-center p-8 bg-gradient-to-br from-orange-50/40 via-amber-50/40 to-yellow-50/40 dark:from-gray-900/40 dark:via-gray-800/40 dark:to-gray-700/40"
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.3, duration: 0.5 }}
@@ -284,20 +281,22 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
<div className="w-full h-full max-w-2xl max-h-2xl">
<motion.div
animate={{
rotateY: autoRotate ? 360 : 0,
scale: isPlaying ? 1.02 : 1
scale: isPlaying ? 1.02 : 1,
y: isPlaying ? -5 : 0
}}
transition={{
rotateY: { duration: 10, repeat: Infinity, ease: "linear" },
scale: { duration: 0.2 }
scale: { duration: 0.2 },
y: { duration: 0.2 }
}}
className="relative"
>
<div className="absolute inset-0 bg-gradient-to-br from-orange-400/20 to-amber-400/20 dark:from-orange-500/10 dark:to-amber-500/10 rounded-2xl blur-xl"></div>
<SkinViewer
skinUrl={texture.url}
isSlim={texture.is_slim}
width={600}
height={600}
className="w-full h-full rounded-xl shadow-2xl border-2 border-white/50 dark:border-gray-700/50"
className="w-full h-full rounded-2xl shadow-2xl border-2 border-white/60 dark:border-gray-600/60 relative z-10"
autoRotate={autoRotate}
walking={currentAnimation === 'walking'}
running={currentAnimation === 'running'}
@@ -310,7 +309,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
{/* 控制面板 */}
<motion.div
className="w-80 bg-gradient-to-b from-orange-50/80 to-amber-50/80 dark:from-gray-900/80 dark:to-gray-800/80 backdrop-blur-md border-l border-orange-200/50 dark:border-gray-600/50 p-6 space-y-6 overflow-y-auto custom-scrollbar"
className="w-80 bg-gradient-to-b from-orange-50/90 via-amber-50/90 to-yellow-50/90 dark:from-gray-900/90 dark:via-gray-800/90 dark:to-gray-700/90 backdrop-blur-xl border-l border-orange-200/60 dark:border-gray-600/60 p-6 space-y-6 overflow-y-auto custom-scrollbar shadow-inner"
initial={{ opacity: 0, x: 50 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.4, duration: 0.5 }}
@@ -318,12 +317,12 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
{/* 动画控制 */}
<motion.div className="space-y-4">
<motion.h3
className="text-lg font-semibold bg-gradient-to-r from-orange-500 to-amber-500 bg-clip-text text-transparent flex items-center"
className="text-xl font-bold bg-gradient-to-r from-orange-500 via-amber-500 to-yellow-500 bg-clip-text text-transparent flex items-center drop-shadow-sm"
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.5 }}
>
<PlayIcon className="w-5 h-5 mr-2" />
<PlayIcon className="w-6 h-6 mr-3" />
</motion.h3>
@@ -337,18 +336,17 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
<motion.button
key={anim.key}
variants={getAnimationButtonVariants(currentAnimation === anim.key)}
initial="initial"
animate={currentAnimation === anim.key ? "active" : "animate"}
whileHover="hover"
whileTap="tap"
onClick={() => handleAnimationChange(anim.key as any)}
className={`p-3 rounded-lg text-sm font-medium transition-all duration-200 ${
className={`p-4 rounded-xl text-sm font-semibold transition-all duration-300 transform ${
currentAnimation === anim.key
? 'bg-gradient-to-r from-orange-500 to-amber-500 text-white shadow-lg transform scale-105'
: 'bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-orange-100 dark:hover:bg-orange-900/20 border border-orange-200 dark:border-gray-600 hover:border-orange-300 dark:hover:border-orange-500'
? 'bg-gradient-to-r from-orange-500 via-amber-500 to-yellow-500 text-white shadow-2xl scale-105 ring-2 ring-orange-300 dark:ring-orange-500'
: 'bg-white/80 dark:bg-gray-700/80 text-gray-700 dark:text-gray-300 hover:bg-orange-50 dark:hover:bg-orange-900/30 border border-orange-200/50 dark:border-gray-600 hover:border-orange-300 dark:hover:border-orange-400 hover:scale-105 hover:shadow-lg'
}`}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.6 + i * 0.1 }}
>
{anim.label}
@@ -364,18 +362,18 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
animate={{ opacity: 1 }}
transition={{ delay: 0.8 }}
>
<h3 className="text-lg font-semibold bg-gradient-to-r from-orange-500 to-amber-500 bg-clip-text text-transparent">
<h3 className="text-xl font-bold bg-gradient-to-r from-orange-500 via-amber-500 to-yellow-500 bg-clip-text text-transparent drop-shadow-sm">
</h3>
{texture.description && (
<motion.div
className="bg-white/50 dark:bg-gray-700/50 rounded-lg p-3"
className="bg-white/70 dark:bg-gray-700/70 rounded-xl p-4 shadow-md border border-white/30 dark:border-gray-600/30"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.9 }}
>
<p className="text-sm text-gray-700 dark:text-gray-300 leading-relaxed">
<p className="text-sm text-gray-700 dark:text-gray-300 leading-relaxed font-medium">
{texture.description}
</p>
</motion.div>
@@ -432,13 +430,21 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
{/* 快捷键提示 */}
<motion.div
className="bg-white/30 dark:bg-gray-700/30 rounded-lg p-3 text-xs text-gray-600 dark:text-gray-400"
className="bg-gradient-to-r from-orange-100/50 to-amber-100/50 dark:from-gray-700/50 dark:to-gray-600/50 rounded-xl p-4 text-xs text-gray-600 dark:text-gray-400 border border-orange-200/30 dark:border-gray-600/30"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 1.4 }}
>
<p className="font-medium mb-1">:</p>
<p> - / | 1-4 - | M - | ESC - </p>
<p className="font-bold mb-2 text-orange-700 dark:text-orange-300 flex items-center">
<span className="w-2 h-2 bg-orange-500 rounded-full mr-2"></span>
</p>
<div className="grid grid-cols-2 gap-2 text-xs">
<div className="flex items-center"><kbd className="px-2 py-1 bg-white/70 dark:bg-gray-800/70 rounded border border-gray-300 dark:border-gray-600 text-xs mr-2"></kbd>/</div>
<div className="flex items-center"><kbd className="px-2 py-1 bg-white/70 dark:bg-gray-800/70 rounded border border-gray-300 dark:border-gray-600 text-xs mr-2">1-4</kbd></div>
<div className="flex items-center"><kbd className="px-2 py-1 bg-white/70 dark:bg-gray-800/70 rounded border border-gray-300 dark:border-gray-600 text-xs mr-2">M</kbd></div>
<div className="flex items-center"><kbd className="px-2 py-1 bg-white/70 dark:bg-gray-800/70 rounded border border-gray-300 dark:border-gray-600 text-xs mr-2">ESC</kbd></div>
</div>
</motion.div>
</motion.div>
</div>
@@ -453,11 +459,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
transition={{ delay: 0.2 }}
>
<div className="text-center">
<motion.div
animate={{ rotate: autoRotate ? 360 : 0 }}
transition={{ rotate: { duration: 5, repeat: Infinity, ease: "linear" } }}
className="w-20 h-20 mx-auto mb-2"
>
<div className="w-20 h-20 mx-auto mb-2">
<SkinViewer
skinUrl={texture.url}
isSlim={texture.is_slim}
@@ -468,7 +470,7 @@ export default function SkinDetailModal({ isOpen, onClose, texture, isExternalPr
running={currentAnimation === 'running'}
jumping={currentAnimation === 'swimming'}
/>
</motion.div>
</div>
<p className="text-sm font-medium text-gray-700 dark:text-gray-300 truncate">
{texture.name}
</p>