feat: main Added rainbow skeleton

This commit is contained in:
Nikolaj Frey 2023-06-28 11:12:17 +10:00
parent 14c508786a
commit fa1c09c9c4
11 changed files with 321 additions and 12 deletions

View 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>
)
}

View 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>
)
}

View 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>
)
}

View 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>
</>
)
}

View 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>
</>
)
}

View 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>
)
}

View 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>
)
}

View File

@ -5,6 +5,7 @@ export const RainbowText = props => {
return (
<Text
as='h1'
position='relative'
fontSize='6xl'
fontWeight='bold'
backgroundClip={'text'}

View File

@ -1,3 +1,4 @@
import { Box } from '@chakra-ui/react'
import { RainbowText } from './rainbowText'
import React from 'react'
@ -5,27 +6,28 @@ export const TextAnimation1 = props => {
const texts = React.useMemo(() => {
return [
'thingtime',
'creative',
'tt',
'vibrant',
'powerful',
'love',
'infinite',
'creative',
'powerful',
'magical',
'inspiring'
'inspiring',
'love',
'tt'
]
}, [])
const [titleText, setTitleText] = React.useState(texts[0])
React.useEffect(() => {
const newTimeout = Math.random() * 3500 + 1500
const newTimeout = Math.random() * 1500 + 2500
setTimeout(() => {
let newTextIdx = Math.round(Math.random() * (texts.length - 1))
if (newTextIdx === texts.indexOf(titleText)) {
newTextIdx = newTextIdx + 1
}
// let newTextIdx = Math.round(Math.random() * (texts.length - 1))
let newTextIdx = texts?.indexOf(titleText) + 1
// if (newTextIdx === texts.indexOf(titleText)) {
// newTextIdx = newTextIdx + 1
// }
const newText = texts[newTextIdx] || texts[0]
setTitleText(newText)
}, newTimeout)

View File

@ -9,6 +9,7 @@ import {
ScrollRestoration
} from '@remix-run/react'
import { Analytics } from '@vercel/analytics/react'
import { Main } from './components/Layout/Main'
function Document ({
children,
@ -27,7 +28,7 @@ function Document ({
<Links />
</head>
<body>
{children}
<Main>{children}</Main>
<ScrollRestoration />
<Scripts />
<LiveReload />

View File

@ -3,7 +3,7 @@
"sideEffects": false,
"scripts": {
"build": "remix build",
"dev": "remix dev"
"dev": "remix dev --port 9999"
},
"dependencies": {
"@chakra-ui/react": "^2.7.1",