114 lines
3.4 KiB
TypeScript
114 lines
3.4 KiB
TypeScript
import Box from '@mui/material/Box';
|
|
import Typography from '@mui/material/Typography';
|
|
import Fade from '@mui/material/Fade';
|
|
|
|
interface FullScreenLoaderProps {
|
|
message?: string;
|
|
fullScreen?: boolean;
|
|
}
|
|
|
|
export const FullScreenLoader = ({
|
|
message,
|
|
fullScreen = true,
|
|
}: FullScreenLoaderProps) => {
|
|
const containerSx = fullScreen
|
|
? {
|
|
position: 'fixed' as const,
|
|
inset: 0,
|
|
display: 'flex',
|
|
flexDirection: 'column' as const,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
gap: 3,
|
|
zIndex: 9999,
|
|
pointerEvents: 'none' as const,
|
|
}
|
|
: {
|
|
display: 'flex',
|
|
flexDirection: 'column' as const,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
gap: 3,
|
|
width: '100%',
|
|
height: '100%',
|
|
};
|
|
|
|
return (
|
|
<Box sx={containerSx}>
|
|
{/* Плавное появление фона */}
|
|
{fullScreen && (
|
|
<Fade in timeout={220} appear>
|
|
<Box
|
|
className="glass-ui"
|
|
sx={{
|
|
position: 'absolute',
|
|
inset: 0,
|
|
background:
|
|
'radial-gradient(circle at 15% 20%, rgba(242,113,33,0.15), transparent 60%), radial-gradient(circle at 85% 10%, rgba(233,64,205,0.12), transparent 55%), rgba(5,5,10,0.75)',
|
|
}}
|
|
/>
|
|
</Fade>
|
|
)}
|
|
|
|
{/* Плавное появление контента */}
|
|
<Fade in timeout={260} appear>
|
|
<Box
|
|
sx={{
|
|
zIndex: 1,
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
alignItems: 'center',
|
|
gap: 3,
|
|
// небольшой "подъём" при появлении
|
|
animation: document.body.classList.contains('reduce-motion')
|
|
? 'none'
|
|
: 'popIn 260ms ease-out both',
|
|
'@keyframes popIn': {
|
|
from: { opacity: 0, transform: 'translateY(8px) scale(0.98)' },
|
|
to: { opacity: 1, transform: 'translateY(0) scale(1)' },
|
|
},
|
|
}}
|
|
>
|
|
<Box
|
|
sx={{
|
|
width: 80,
|
|
height: 80,
|
|
borderRadius: '50%',
|
|
position: 'relative',
|
|
overflow: 'hidden',
|
|
background: 'conic-gradient(#F27121, #E940CD, #8A2387, #F27121)',
|
|
animation: document.body.classList.contains('reduce-motion')
|
|
? 'none'
|
|
: 'spin 1s linear infinite',
|
|
WebkitMask: 'radial-gradient(circle, transparent 55%, black 56%)',
|
|
mask: 'radial-gradient(circle, transparent 55%, black 56%)',
|
|
'@keyframes spin': {
|
|
'0%': { transform: 'rotate(0deg)' },
|
|
'100%': { transform: 'rotate(360deg)' },
|
|
},
|
|
boxShadow: '0 0 2.5vw rgba(233,64,205,0.45)',
|
|
}}
|
|
/>
|
|
|
|
{message && (
|
|
<Typography
|
|
variant="h6"
|
|
sx={{
|
|
fontFamily: 'Benzin-Bold',
|
|
background:
|
|
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)',
|
|
WebkitBackgroundClip: 'text',
|
|
WebkitTextFillColor: 'transparent',
|
|
textAlign: 'center',
|
|
textShadow: '0 0 1.2vw rgba(0,0,0,0.45)',
|
|
}}
|
|
>
|
|
{message}
|
|
</Typography>
|
|
)}
|
|
</Box>
|
|
</Fade>
|
|
</Box>
|
|
);
|
|
};
|