forked from mirror/chinese-colors
feat: code splitting with react lazy & suspense
This commit is contained in:
parent
8785781cd3
commit
c5bb2883d7
37
src/App.js
37
src/App.js
@ -1,17 +1,30 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, lazy, Suspense } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import pinyin from 'pinyin';
|
||||
import convert from 'color-convert';
|
||||
import ColorTitle from './components/ColorTitle';
|
||||
import Color from './components/Color';
|
||||
import Preview from './components/Preview';
|
||||
import ColorParam from './components/ColorParam';
|
||||
import InfoModal from './components/InfoModal';
|
||||
import IconInfo from './components/IconInfo';
|
||||
import IconScreenshot from './components/IconScreenshot';
|
||||
import Header from './components/Header';
|
||||
import ColorSet from './components/ColorSet';
|
||||
import Loading from './components/Loading';
|
||||
const ColorTitle = lazy(() => import('./components/ColorTitle'));
|
||||
const Color = lazy(() => import('./components/Color'));
|
||||
const Preview = lazy(() => import('./components/Preview'));
|
||||
const ColorParam = lazy(() => import('./components/ColorParam'));
|
||||
const InfoModal = lazy(() => import('./components/InfoModal'));
|
||||
const IconInfo = lazy(() => import('./components/IconInfo'));
|
||||
const Header = lazy(() => import('./components/Header'));
|
||||
const IconScreenshot = lazy(() => import('./components/IconScreenshot'));
|
||||
const ColorSet = lazy(() => import('./components/ColorSet'));
|
||||
|
||||
// import ColorTitle from './components/ColorTitle';
|
||||
// import Color from './components/Color';
|
||||
// import Preview from './components/Preview';
|
||||
// import ColorParam from './components/ColorParam';
|
||||
// import InfoModal from './components/InfoModal';
|
||||
// import IconInfo from './components/IconInfo';
|
||||
// import IconScreenshot from './components/IconScreenshot';
|
||||
// import Header from './components/Header';
|
||||
// import ColorSet from './components/ColorSet';
|
||||
|
||||
import { useModal, useColor, usePreview } from './hooks';
|
||||
|
||||
import colors from './assets/colors.json';
|
||||
|
||||
colors.push({
|
||||
@ -100,7 +113,7 @@ const App = () => {
|
||||
document.body.style.backgroundColor = currColor.hex;
|
||||
}, [currColor]);
|
||||
return (
|
||||
<>
|
||||
<Suspense fallback={<Loading color="#000" size="4" sizeUnit="rem" />}>
|
||||
<Wrapper>
|
||||
<aside className="colorSet">
|
||||
<ColorSet sets={sets} currSetName={currSet.name} setCurrSet={updateCurrSet} />
|
||||
@ -138,7 +151,7 @@ const App = () => {
|
||||
/>
|
||||
)}
|
||||
{modalVisible && <InfoModal bgColor={currColor.hex} closeModal={closeModal} />}
|
||||
</>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
export default App;
|
||||
|
@ -8,8 +8,8 @@ const Wrapper = styled.aside`
|
||||
align-items: center;
|
||||
margin-bottom: 0.8rem;
|
||||
.icon {
|
||||
width: 1.8rem;
|
||||
height: 1.8rem;
|
||||
width: 1.4rem;
|
||||
height: 1.4rem;
|
||||
}
|
||||
`;
|
||||
|
||||
|
113
src/components/Loading.js
Normal file
113
src/components/Loading.js
Normal file
@ -0,0 +1,113 @@
|
||||
import React from 'react';
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
const rotate = keyframes`
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100%{
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
`;
|
||||
|
||||
const rotateBall = props => keyframes`
|
||||
${(((props.size / 2 / props.countBalls) * (props.index - 1)) / props.size) * 100}% {
|
||||
opacity: 0;
|
||||
}
|
||||
${(((props.size / 2 / props.countBalls + 0.0001) * (props.index - 1)) / props.size) * 100}% {
|
||||
opacity: 1;
|
||||
transform: ${`rotateZ(${0 - (360 / props.countBalls) * (props.index - 2)}deg)`};
|
||||
}
|
||||
${(((props.size / 2 / props.countBalls) * (props.index - 0) + 2) / props.size) * 100}% {
|
||||
transform: ${`rotateZ(${0 - (360 / props.countBalls) * (props.index - 1)}deg)`};
|
||||
}
|
||||
${((props.size / 2 + (props.size / 2 / props.countBalls) * (props.index - 0) + 2) / props.size) *
|
||||
100}% {
|
||||
transform: ${`rotateZ(${0 - (360 / props.countBalls) * (props.index - 1)}deg)`};
|
||||
}
|
||||
100% {
|
||||
transform: ${`rotateZ(${0 - (360 / props.countBalls) * (props.countBalls - 1)}deg)`};
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const getBalls = ({
|
||||
countBalls,
|
||||
radius,
|
||||
angle,
|
||||
color = '#fff',
|
||||
size = 40,
|
||||
ballSize,
|
||||
sizeUnit = 'px'
|
||||
}) => {
|
||||
const balls = [];
|
||||
const offset = ballSize / 2;
|
||||
for (let i = 0; i < countBalls; i++) {
|
||||
const y = Math.sin(angle * i * (Math.PI / 180)) * radius - offset;
|
||||
const x = Math.cos(angle * i * (Math.PI / 180)) * radius - offset;
|
||||
balls.push(
|
||||
<Ball
|
||||
countBalls={countBalls}
|
||||
color={color}
|
||||
ballSize={ballSize}
|
||||
size={size}
|
||||
sizeUnit={sizeUnit}
|
||||
x={y}
|
||||
y={x}
|
||||
key={i.toString()}
|
||||
index={i + 1}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return balls;
|
||||
};
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
animation: ${rotate} 3s infinite ease-in;
|
||||
`;
|
||||
|
||||
const Ball = styled.div`
|
||||
position: absolute;
|
||||
width: ${props => `${props.size}${props.sizeUnit}`};
|
||||
height: ${props => `${props.size}${props.sizeUnit}`};
|
||||
animation: ${rotateBall} 2s infinite linear;
|
||||
transform: ${props => `rotateZ(${(360 / props.countBalls) * props.index}deg)`};
|
||||
opacity: 0;
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0%;
|
||||
width: ${props => `${props.ballSize}${props.sizeUnit}`};
|
||||
height: ${props => `${props.ballSize}${props.sizeUnit}`};
|
||||
background-color: ${props => `${props.color}`};
|
||||
transform: translateX(-50%);
|
||||
border-radius: 50%;
|
||||
}
|
||||
`;
|
||||
|
||||
const Loading = ({ size = 40, color = '#fff', sizeUnit = 'px' }) => {
|
||||
const radius = size / 2;
|
||||
const countBalls = 9;
|
||||
const ballSize = size / 8;
|
||||
const angle = 360 / countBalls;
|
||||
return (
|
||||
<Wrapper size={size} sizeUnit={sizeUnit}>
|
||||
{getBalls({
|
||||
countBalls,
|
||||
radius,
|
||||
angle,
|
||||
color,
|
||||
size,
|
||||
ballSize,
|
||||
sizeUnit
|
||||
})}
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
export default Loading;
|
Loading…
Reference in New Issue
Block a user