feat: main Added rainbow skeleton
This commit is contained in:
parent
14c508786a
commit
fa1c09c9c4
32
remix/app/components/Buttons/Attention.tsx
Normal file
32
remix/app/components/Buttons/Attention.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Flex } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const Attention = props => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
{...props}
|
||||||
|
flexDirection={'column'}
|
||||||
|
justifyContent={'center'}
|
||||||
|
alignItems={'center'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
w={props.w || '40px'}
|
||||||
|
mb='10px'
|
||||||
|
h='2px'
|
||||||
|
bg='linear-gradient(to right, #f34a4a, #ffbc48, #58ca70, #47b5e6, #a555e8, #f34a4a);'
|
||||||
|
backgroundSize='200%'
|
||||||
|
borderBottomRadius={'20px'}
|
||||||
|
transition='all 0.5s ease-in-out'
|
||||||
|
sx={{
|
||||||
|
'@keyframes moving-rainbow': {
|
||||||
|
'0%': { backgroundPosition: '0 0' },
|
||||||
|
'100%': { backgroundPosition: '200% 0' }
|
||||||
|
},
|
||||||
|
// add delay
|
||||||
|
animation: `moving-rainbow 3s infinite linear`
|
||||||
|
}}
|
||||||
|
></Flex>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
38
remix/app/components/Buttons/Hamburger.tsx
Normal file
38
remix/app/components/Buttons/Hamburger.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Flex } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const Hamburger = props => {
|
||||||
|
const lineCount = [1, 2, 3]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
{...props}
|
||||||
|
flexDirection={'column'}
|
||||||
|
justifyContent={'center'}
|
||||||
|
alignItems={'center'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
>
|
||||||
|
{lineCount.map((line, idx) => {
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
key={idx}
|
||||||
|
w='40px'
|
||||||
|
mb='10px'
|
||||||
|
h='3px'
|
||||||
|
bg='linear-gradient(to right, #f34a4a, #ffbc48, #58ca70, #47b5e6, #a555e8, #f34a4a);'
|
||||||
|
backgroundSize='200%'
|
||||||
|
borderRadius={'9px'}
|
||||||
|
sx={{
|
||||||
|
'@keyframes moving-rainbow': {
|
||||||
|
'0%': { backgroundPosition: '0 0' },
|
||||||
|
'100%': { backgroundPosition: '200% 0' }
|
||||||
|
},
|
||||||
|
// add delay
|
||||||
|
animation: `moving-rainbow 3s infinite linear -${idx * 0.3}s}`
|
||||||
|
}}
|
||||||
|
></Flex>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
11
remix/app/components/Layout/Main.tsx
Normal file
11
remix/app/components/Layout/Main.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Flex } from '@chakra-ui/react'
|
||||||
|
import { Nav } from '../Nav/Nav'
|
||||||
|
|
||||||
|
export const Main = props => {
|
||||||
|
return (
|
||||||
|
<Flex alignItems='center' justifyContent='center' flexDir={'column'}>
|
||||||
|
<Nav />
|
||||||
|
{props.children}
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
26
remix/app/components/Nav/Nav.tsx
Normal file
26
remix/app/components/Nav/Nav.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Flex } from '@chakra-ui/react'
|
||||||
|
import { RainbowSkeleton } from '../Skeleton/RainbowSkeleton'
|
||||||
|
|
||||||
|
export const Nav = props => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Flex
|
||||||
|
as='nav'
|
||||||
|
w='100%'
|
||||||
|
alignItems={'center'}
|
||||||
|
justifyContent='center'
|
||||||
|
flexDir={'row'}
|
||||||
|
position='fixed'
|
||||||
|
top={0}
|
||||||
|
left={0}
|
||||||
|
right={0}
|
||||||
|
py={4}
|
||||||
|
px={4}
|
||||||
|
>
|
||||||
|
<RainbowSkeleton w='40px' ml='auto' mr={"4px"}></RainbowSkeleton>
|
||||||
|
<RainbowSkeleton></RainbowSkeleton>
|
||||||
|
</Flex>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
69
remix/app/components/Nav/ReactiveNav.tsx
Normal file
69
remix/app/components/Nav/ReactiveNav.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Flex } from '@chakra-ui/react'
|
||||||
|
import { Hamburger } from '../Buttons/Hamburger'
|
||||||
|
import { Attention } from '../Buttons/Attention'
|
||||||
|
import { RightNav } from './ReactiveRightNav'
|
||||||
|
|
||||||
|
export const ReactiveNav = props => {
|
||||||
|
const [navItems] = React.useState([{}])
|
||||||
|
|
||||||
|
const setNav = React.useCallback(active => {
|
||||||
|
setMt(active ? '100%' : '0%')
|
||||||
|
setNavActive(active)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
// react to mouse move event
|
||||||
|
const listener = event => {
|
||||||
|
if (event?.clientY <= 20) {
|
||||||
|
setNav(true)
|
||||||
|
} else if (event?.clientY >= 100) {
|
||||||
|
setNav(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('mousemove', listener)
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('mousemove', listener)
|
||||||
|
}
|
||||||
|
}, [setNav])
|
||||||
|
|
||||||
|
const [navActive, setNavActive] = React.useState(false)
|
||||||
|
|
||||||
|
const [mt, setMt] = React.useState('0%')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Flex
|
||||||
|
as='nav'
|
||||||
|
w='100%'
|
||||||
|
alignItems={'center'}
|
||||||
|
justifyContent='center'
|
||||||
|
flexDir={'row'}
|
||||||
|
position='fixed'
|
||||||
|
py={'1%'}
|
||||||
|
px={'1%'}
|
||||||
|
bottom={'100%'}
|
||||||
|
transform={`translateY(${mt})`}
|
||||||
|
transition={'all 0.3s ease-in-out'}
|
||||||
|
// top={'100%'}
|
||||||
|
// top={0}
|
||||||
|
left={0}
|
||||||
|
right={0}
|
||||||
|
>
|
||||||
|
<Hamburger ml='auto'></Hamburger>
|
||||||
|
<Flex
|
||||||
|
opacity={navActive ? 0 : 1}
|
||||||
|
position='absolute'
|
||||||
|
transition={'all 0.2s ease-in-out'}
|
||||||
|
top='100%'
|
||||||
|
left={'50%'}
|
||||||
|
translateX={'-50%'}
|
||||||
|
>
|
||||||
|
{/* w={navActive ? '0px' : '40px'} */}
|
||||||
|
<Attention></Attention>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
<RightNav></RightNav>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
82
remix/app/components/Nav/ReactiveRightNav.tsx
Normal file
82
remix/app/components/Nav/ReactiveRightNav.tsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Center, Text } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const ReactiveRightNav = props => {
|
||||||
|
const setNav = React.useCallback(active => {
|
||||||
|
setMr(active ? '0%' : '-100%')
|
||||||
|
setNavActive(active)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const [entered, setEntered] = React.useState(false)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
// react to mouse move event
|
||||||
|
const listener = event => {
|
||||||
|
const windowWidth = window.innerWidth
|
||||||
|
if (!entered) {
|
||||||
|
if (event?.clientX >= windowWidth - 60) {
|
||||||
|
setNav(true)
|
||||||
|
} else if (event?.clientX <= windowWidth - 100) {
|
||||||
|
setNav(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('mousemove', listener)
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('mousemove', listener)
|
||||||
|
}
|
||||||
|
}, [setNav, entered])
|
||||||
|
|
||||||
|
const [navActive, setNavActive] = React.useState(false)
|
||||||
|
|
||||||
|
// const defaultMr = '-100%'
|
||||||
|
const defaultMr = '0%'
|
||||||
|
|
||||||
|
const [mr, setMr] = React.useState(defaultMr)
|
||||||
|
|
||||||
|
const navItems = React.useMemo(() => {
|
||||||
|
return ['home', 'imagine', 'create', 'share']
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Center
|
||||||
|
mr={mr}
|
||||||
|
transition={'all 0.3s ease-in-out'}
|
||||||
|
position='fixed'
|
||||||
|
top={0}
|
||||||
|
right={0}
|
||||||
|
h='100%'
|
||||||
|
flexDir='column'
|
||||||
|
>
|
||||||
|
<Center
|
||||||
|
onMouseEnter={() => setEntered(true)}
|
||||||
|
onMouseLeave={() => setEntered(false)}
|
||||||
|
flexDir={'column'}
|
||||||
|
borderLeftRadius={'40px'}
|
||||||
|
h='85%'
|
||||||
|
minW={'600px'}
|
||||||
|
maxW='100%'
|
||||||
|
py={80}
|
||||||
|
px={100}
|
||||||
|
bg={`rgba(0, 0, 0, 0.01)`}
|
||||||
|
>
|
||||||
|
{navItems.map((navItem, idx) => {
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
color='black'
|
||||||
|
my={'auto'}
|
||||||
|
fontWeight='semibold'
|
||||||
|
key={idx}
|
||||||
|
textTransform={'capitalize'}
|
||||||
|
as='h2'
|
||||||
|
cursor='pointer'
|
||||||
|
fontSize='30px'
|
||||||
|
>
|
||||||
|
{navItem}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Center>
|
||||||
|
</Center>
|
||||||
|
)
|
||||||
|
}
|
47
remix/app/components/Skeleton/RainbowSkeleton.tsx
Normal file
47
remix/app/components/Skeleton/RainbowSkeleton.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Flex } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const RainbowSkeleton = props => {
|
||||||
|
|
||||||
|
const [rainbowColours] = React.useState(["#f34a4a", "#ffbc48", "#58ca70", "#47b5e6", "#a555e8"])
|
||||||
|
|
||||||
|
const keyframes = React.useMemo(() => {
|
||||||
|
let keyframes = {}
|
||||||
|
rainbowColours.forEach((colour, idx) => {
|
||||||
|
keyframes[Math.round(idx * 100 / rainbowColours.length) + "%"] = { backgroundColor: colour }
|
||||||
|
})
|
||||||
|
keyframes["100%"] = { backgroundColor: rainbowColours[0] }
|
||||||
|
return keyframes
|
||||||
|
}, [rainbowColours])
|
||||||
|
|
||||||
|
if (props?.loaded) {
|
||||||
|
return props?.children
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex
|
||||||
|
{...props}
|
||||||
|
flexDirection={'column'}
|
||||||
|
justifyContent={'center'}
|
||||||
|
alignItems={'center'}
|
||||||
|
cursor={'pointer'}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
w='10px'
|
||||||
|
h='8px'
|
||||||
|
borderRadius={'2px'}
|
||||||
|
mb='10px'
|
||||||
|
sx={{
|
||||||
|
'@keyframes placeholder-rainbow': keyframes,
|
||||||
|
'@keyframes placeholder-opacity': {
|
||||||
|
'0%': { opacity: 0.2 },
|
||||||
|
'100%': { opacity: 1 }
|
||||||
|
},
|
||||||
|
// add delay
|
||||||
|
animation: `placeholder-rainbow 3s infinite linear, placeholder-opacity 1.3s linear 0s infinite alternate none running}`
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
></Flex>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
}
|
@ -5,6 +5,7 @@ export const RainbowText = props => {
|
|||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
as='h1'
|
as='h1'
|
||||||
|
position='relative'
|
||||||
fontSize='6xl'
|
fontSize='6xl'
|
||||||
fontWeight='bold'
|
fontWeight='bold'
|
||||||
backgroundClip={'text'}
|
backgroundClip={'text'}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { Box } from '@chakra-ui/react'
|
||||||
import { RainbowText } from './rainbowText'
|
import { RainbowText } from './rainbowText'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
@ -5,27 +6,28 @@ export const TextAnimation1 = props => {
|
|||||||
const texts = React.useMemo(() => {
|
const texts = React.useMemo(() => {
|
||||||
return [
|
return [
|
||||||
'thingtime',
|
'thingtime',
|
||||||
'creative',
|
|
||||||
'tt',
|
|
||||||
'vibrant',
|
'vibrant',
|
||||||
'powerful',
|
|
||||||
'love',
|
|
||||||
'infinite',
|
'infinite',
|
||||||
|
'creative',
|
||||||
|
'powerful',
|
||||||
'magical',
|
'magical',
|
||||||
'inspiring'
|
'inspiring',
|
||||||
|
'love',
|
||||||
|
'tt'
|
||||||
]
|
]
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const [titleText, setTitleText] = React.useState(texts[0])
|
const [titleText, setTitleText] = React.useState(texts[0])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const newTimeout = Math.random() * 3500 + 1500
|
const newTimeout = Math.random() * 1500 + 2500
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let newTextIdx = Math.round(Math.random() * (texts.length - 1))
|
// let newTextIdx = Math.round(Math.random() * (texts.length - 1))
|
||||||
if (newTextIdx === texts.indexOf(titleText)) {
|
let newTextIdx = texts?.indexOf(titleText) + 1
|
||||||
newTextIdx = newTextIdx + 1
|
// if (newTextIdx === texts.indexOf(titleText)) {
|
||||||
}
|
// newTextIdx = newTextIdx + 1
|
||||||
|
// }
|
||||||
const newText = texts[newTextIdx] || texts[0]
|
const newText = texts[newTextIdx] || texts[0]
|
||||||
setTitleText(newText)
|
setTitleText(newText)
|
||||||
}, newTimeout)
|
}, newTimeout)
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
ScrollRestoration
|
ScrollRestoration
|
||||||
} from '@remix-run/react'
|
} from '@remix-run/react'
|
||||||
import { Analytics } from '@vercel/analytics/react'
|
import { Analytics } from '@vercel/analytics/react'
|
||||||
|
import { Main } from './components/Layout/Main'
|
||||||
|
|
||||||
function Document ({
|
function Document ({
|
||||||
children,
|
children,
|
||||||
@ -27,7 +28,7 @@ function Document ({
|
|||||||
<Links />
|
<Links />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{children}
|
<Main>{children}</Main>
|
||||||
<ScrollRestoration />
|
<ScrollRestoration />
|
||||||
<Scripts />
|
<Scripts />
|
||||||
<LiveReload />
|
<LiveReload />
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "remix build",
|
"build": "remix build",
|
||||||
"dev": "remix dev"
|
"dev": "remix dev --port 9999"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/react": "^2.7.1",
|
"@chakra-ui/react": "^2.7.1",
|
||||||
|
Loading…
Reference in New Issue
Block a user