feat: enhance MAA website animation for a more elegant appearance (#11303)

* feat: enhance MAA website animation for a more elegant appearance

* fix: briefly appears scrollbar which cause a bad animation apperance.
This commit is contained in:
__Chisato__
2024-12-07 00:53:15 +08:00
committed by GitHub
parent 68776ea8af
commit b3d4269476
6 changed files with 85 additions and 26 deletions

View File

@@ -2,7 +2,7 @@ import { HomeHero } from './components/home/HomeHero'
function App() {
return (
<main className="h-full">
<main className="h-full max-h-screen overflow-hidden">
<section className="h-screen min-h-[20rem] w-full relative">
<HomeHero />
</section>

View File

@@ -21,28 +21,33 @@ export const GlowButton: FCC<GlowButtonProps> = forwardRef<
>(({ children, translucent, bordered, href, onClick }, ref) => {
const motionConfig: MotionProps = {
whileHover: {
scale: 1.03,
scale: 1.05,
backgroundColor: translucent ? 'rgba(39, 39, 42, 0.6)' : 'rgba(39, 39, 42, 0.8)',
},
whileTap: {
scale: 0.97,
scale: 0.95,
backgroundColor: 'rgba(39, 39, 42, 0.7)',
},
exit: {
scale: 0.4,
opacity: 0,
filter: 'blur(10px)',
},
initial: {
scale: 0.4,
opacity: 0,
filter: 'blur(10px)',
},
animate: {
scale: 1,
opacity: 1,
filter: 'blur(0px)',
},
transition: {
type: 'spring',
stiffness: 400,
stiffness: 200,
damping: 30,
mass: 1.2,
mass: 0.8,
},
}
@@ -53,7 +58,7 @@ export const GlowButton: FCC<GlowButtonProps> = forwardRef<
className={clsx(
moduleStyles.root,
!translucent && 'bg-zinc-900/80',
translucent && 'bg-zinc-900/80 hover:bg-zinc-700/40',
translucent && 'bg-zinc-900/80',
!bordered && 'border-none',
'flex px-6 py-3 active:bg-zinc-800 rounded-lg hover:-translate-y-[1px] active:translate-y-[1px] text-2xl text-white/80 whitespace-nowrap',
)}

View File

@@ -1,4 +1,5 @@
import clsx from 'clsx'
import { motion } from 'framer-motion'
const blobs = [
['bg-red-900 translate-y-36', 'left-[30%]'],
@@ -12,9 +13,13 @@ export function AnimatedBlobs() {
<div className="absolute h-full w-full overflow-hidden transform-gpu blur-[9rem] left-[-10rem] top-[-10rem]">
{blobs.map((blob, i) => (
<div key={i} className={clsx('absolute top-[50vh]', blob[1])}>
<div
className={clsx('h-[20rem] w-[20rem] rounded-full', blob[0])}
></div>
<motion.div
initial={{ opacity: 0, y: 50, filter: 'blur(10px)' }}
animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}
transition={{ duration: 0.8, ease: 'easeOut', delay: 0.1 }}
>
<div className={clsx('h-[20rem] w-[20rem] rounded-full', blob[0])}></div>
</motion.div>
</div>
))}
</div>

View File

@@ -27,7 +27,7 @@ export const HomeActions: FC = () => {
<DownloadState
iconClassName="animate-spin"
icon={mdiLoading}
title="正在载入版本信息..."
title = ""
/>
}
>

View File

@@ -1,6 +1,7 @@
import { PerformanceMonitor } from '@react-three/drei'
import { Canvas } from '@react-three/fiber'
import { ErrorBoundary } from '@sentry/react'
import { motion } from 'framer-motion'
import { FC, forwardRef, useRef, useState } from 'react'
import { useWindowSize } from 'react-use'
@@ -19,7 +20,12 @@ export const HomeHero: FC = () => {
return (
<>
<AnimatedBlobs />
<div className="absolute h-full w-full flex items-center">
<motion.div
className="absolute h-full w-full flex items-center"
initial={{ opacity: 0, y: 50, filter: 'blur(10px)' }}
animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}
transition={{ duration: 0.8, ease: 'easeOut', delay: 0.2 }}
>
<section className="h-[100vmin] w-full relative">
{windowDimensions.height >= 768 && (
<ErrorBoundary
@@ -43,8 +49,10 @@ export const HomeHero: FC = () => {
</ErrorBoundary>
)}
</section>
</div>
</motion.div>
<HomeHeroHeader />
<HomeActions />
<HomeLinks ref={linkRef} />
<HomeIndicator ref={indicatorRef} />
@@ -53,14 +61,17 @@ export const HomeHero: FC = () => {
}
const HomeIndicator = forwardRef<HTMLDivElement>((_props, ref) => (
<div
<motion.div
initial={{ opacity: 0, y: 50, filter: 'blur(10px)' }}
animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}
transition={{ duration: 0.8, ease: 'easeOut', delay: 0.6 }}
className="fixed right-[2vw] top-[50vh] pointer-events-none select-none hidden md:block"
ref={ref}
>
<div className="-rotate-90 text-white/20 text-[2rem] font-light">
</div>
</div>
</motion.div>
))
function ScreenshotsCanvas({

View File

@@ -1,18 +1,56 @@
import { motion } from 'framer-motion'
import { FC } from 'react'
export const HomeHeroHeader: FC = () => {
return (
<header className="h-full w-full text-white opacity-80 pt-24 md:pt-[10vh]">
<div className="flex flex-col items-center justify-center px-4">
<h1 className="text-3xl md:text-5xl font-logo font-light mb-4 select-none">
MaaAssistantArknights
</h1>
<p className="text-sm md:text-base px-4 text-center">
<span className="whitespace-nowrap"></span>
<span className="whitespace-nowrap"></span>
<span className="whitespace-nowrap"></span>
</p>
</div>
</header>
<motion.div
initial={{ opacity: 0, y: 30, filter: 'blur(10px)' }}
animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }}
transition={{ duration: 0.8, ease: 'easeOut', delay: 0.3 }}
>
<header className="h-full w-full text-white opacity-80 pt-24 md:pt-[10vh]">
<div className="flex flex-col items-center justify-center px-4">
<motion.h1
className="text-3xl md:text-5xl font-logo font-light mb-4 select-none"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.6, ease: 'easeOut', delay: 0.5 }}
>
MaaAssistantArknights
</motion.h1>
<motion.p
className="text-sm md:text-base px-4 text-center"
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ duration: 0.6, ease: 'easeOut', delay: 0.7 }}
>
<motion.span
className="whitespace-nowrap"
initial={{ opacity: 0, y: 10, rotate: -10 }}
animate={{ opacity: 1, y: 0, rotate: 0 }}
transition={{ duration: 0.5, ease: 'easeOut', delay: 0.8 }}
>
</motion.span>
<motion.span
className="whitespace-nowrap"
initial={{ opacity: 0, y: 10, rotate: 10 }}
animate={{ opacity: 1, y: 0, rotate: 0 }}
transition={{ duration: 0.5, ease: 'easeOut', delay: 1.0 }}
>
</motion.span>
<motion.span
className="whitespace-nowrap"
initial={{ opacity: 0, y: 10, scale: 0.8 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{ duration: 0.5, ease: 'easeOut', delay: 1.2 }}
>
</motion.span>
</motion.p>
</div>
</header>
</motion.div>
)
}