Browse Source

center lines

happy
二货机器人 2 years ago
parent
commit
e21f44e56f
  1. 339
      components/theme/themesToken/happy/style/wave.ts
  2. 132
      components/theme/themesToken/happy/wave.tsx

339
components/theme/themesToken/happy/style/wave.ts

@ -28,7 +28,7 @@ export default function useStyle(tokenConfig: UseTokenType) {
useStyleRegister({ theme, token, hashId, path: ['Customize', 'Wave', 'Effect'] }, () => {
const prefixCls = '.happy-wave';
const { colorPrimary, colorPrimaryBgHover, motionDurationFast, motionDurationSlow } = token;
const activeCls = '&.happy-in-out-leave-active';
const activeCls = '&.happy-in-out-appear-active';
return [
{
@ -48,187 +48,210 @@ export default function useStyle(tokenConfig: UseTokenType) {
[`${prefixCls}-dot`]: {
boxSizing: 'border-box',
position: 'absolute',
width: 8,
height: 8,
// width: 8,
// height: 8,
borderRadius: '100%',
opacity: 0,
transform: 'translate(-50%, -50%)',
display: 'none',
// display: 'none',
// Start Position
// left: '50%',
// top: '50%',
left: `var(--start-x)`,
top: `var(--start-y)`,
width: `var(--size)`,
height: `var(--size)`,
background: `var(--background)`,
border: `var(--border)`,
zIndex: 999,
// =================== Basic Motion ===================
'&.happy-in-out': {
transition: `all ${motionDurationSlow}`,
transition: [
`opacity ${motionDurationSlow} linear`,
`width ${motionDurationSlow} linear`,
`height ${motionDurationSlow} linear`,
`left ${motionDurationSlow} ease-out`,
`top ${motionDurationSlow} ease-out`,
].join(','),
display: 'block',
'&-leave': {
opacity: 1,
'&-appear': {
// opacity: 1,
opacity: 0,
'&-active': {
opacity: 0,
left: `var(--end-x)`,
top: `var(--end-y)`,
// opacity: 0,
opacity: 1,
width: 0,
height: 0,
},
},
},
// Dot 1
'&-1': {
left: 0,
top: 0,
border: `1px solid ${colorPrimary}`,
[activeCls]: {
left: -30,
top: -10,
},
},
// '&-1': {
// left: 0,
// top: 0,
// border: `1px solid ${colorPrimary}`,
// Dot 2
'&-2': {
left: '10%',
top: 0,
width: 4,
height: 4,
background: colorPrimaryBgHover,
[activeCls]: {
left: 'calc(10% - 10px)',
top: -20,
width: 1,
height: 1,
},
},
// [activeCls]: {
// left: -30,
// top: -10,
// },
// },
// Dot 3
'&-3': {
left: '35%',
top: -5,
width: 4,
height: 4,
background: colorPrimary,
opacity: 0.8,
[activeCls]: {
left: 'calc(35% - 3px)',
top: -15,
width: 1,
height: 1,
},
},
// // Dot 2
// '&-2': {
// left: '10%',
// top: 0,
// width: 4,
// height: 4,
// background: colorPrimaryBgHover,
// -----------------------
// Dot 4
'&-4': {
left: '80%',
top: 0,
width: 6,
height: 6,
background: colorPrimaryBgHover,
[activeCls]: {
left: 'calc(80% + 10px)',
top: -20,
width: 1,
height: 1,
},
},
// [activeCls]: {
// left: 'calc(10% - 10px)',
// top: -20,
// width: 1,
// height: 1,
// },
// },
// -----------------------
// Dot 5
'&-5': {
left: '100%',
top: '45%',
width: 10,
height: 10,
background: colorPrimary,
[activeCls]: {
left: 'calc(100% + 20px)',
top: 'calc(45% - 3px)',
width: 1,
height: 1,
},
},
// // Dot 3
// '&-3': {
// left: '35%',
// top: -5,
// width: 4,
// height: 4,
// background: colorPrimary,
// opacity: 0.8,
// Dot 6
'&-6': {
left: '100%',
top: '90%',
width: 4,
height: 4,
background: colorPrimary,
[activeCls]: {
left: 'calc(100% + 30px)',
top: 'calc(90% + 15px)',
width: 1,
height: 1,
},
},
// [activeCls]: {
// left: 'calc(35% - 3px)',
// top: -15,
// width: 1,
// height: 1,
// },
// },
// -----------------------
// Dot 7
'&-7': {
left: '80%',
top: '100%',
width: 10,
height: 10,
background: colorPrimary,
[activeCls]: {
left: 'calc(80% + 10px)',
top: 'calc(100% + 10px)',
width: 1,
height: 1,
},
},
// // -----------------------
// // Dot 4
// '&-4': {
// left: '80%',
// top: 0,
// width: 6,
// height: 6,
// background: colorPrimaryBgHover,
// Dot 8
'&-8': {
left: '55%',
top: '100%',
width: 4,
height: 4,
background: colorPrimaryBgHover,
[activeCls]: {
left: 'calc(55% + 2px)',
top: 'calc(100% + 20px)',
width: 1,
height: 1,
},
},
// [activeCls]: {
// left: 'calc(80% + 10px)',
// top: -20,
// width: 1,
// height: 1,
// },
// },
// Dot 9
'&-9': {
left: 0,
top: '100%',
width: 10,
height: 10,
background: colorPrimaryBgHover,
[activeCls]: {
left: -15,
top: 'calc(100% + 15px)',
width: 1,
height: 1,
},
},
// // -----------------------
// // Dot 5
// '&-5': {
// left: '100%',
// top: '45%',
// width: 10,
// height: 10,
// background: colorPrimary,
// -----------------------
// Dot 10
'&-10': {
left: 0,
top: '50%',
width: 10,
height: 10,
background: colorPrimary,
[activeCls]: {
left: -50,
top: '50%',
width: 1,
height: 1,
},
},
// [activeCls]: {
// left: 'calc(100% + 20px)',
// top: 'calc(45% - 3px)',
// width: 1,
// height: 1,
// },
// },
// // Dot 6
// '&-6': {
// left: '100%',
// top: '90%',
// width: 4,
// height: 4,
// background: colorPrimary,
// [activeCls]: {
// left: 'calc(100% + 30px)',
// top: 'calc(90% + 15px)',
// width: 1,
// height: 1,
// },
// },
// // -----------------------
// // Dot 7
// '&-7': {
// left: '80%',
// top: '100%',
// width: 10,
// height: 10,
// background: colorPrimary,
// [activeCls]: {
// left: 'calc(80% + 10px)',
// top: 'calc(100% + 10px)',
// width: 1,
// height: 1,
// },
// },
// // Dot 8
// '&-8': {
// left: '55%',
// top: '100%',
// width: 4,
// height: 4,
// background: colorPrimaryBgHover,
// [activeCls]: {
// left: 'calc(55% + 2px)',
// top: 'calc(100% + 20px)',
// width: 1,
// height: 1,
// },
// },
// // Dot 9
// '&-9': {
// left: 0,
// top: '100%',
// width: 10,
// height: 10,
// background: colorPrimaryBgHover,
// [activeCls]: {
// left: -15,
// top: 'calc(100% + 15px)',
// width: 1,
// height: 1,
// },
// },
// // -----------------------
// // Dot 10
// '&-10': {
// left: 0,
// top: '50%',
// width: 10,
// height: 10,
// background: colorPrimary,
// [activeCls]: {
// left: -50,
// top: '50%',
// width: 1,
// height: 1,
// },
// },
},
},
},

132
components/theme/themesToken/happy/wave.tsx

@ -1,5 +1,5 @@
import classNames from 'classnames';
import CSSMotion, { CSSMotionList } from 'rc-motion';
import { CSSMotionList } from 'rc-motion';
import raf from 'rc-util/lib/raf';
import * as React from 'react';
import type { ConfigProviderProps } from '../../../config-provider';
@ -15,40 +15,73 @@ interface HappyWaveProps {
const DOT_COUNT = 10;
interface DotInfo {
key: number;
size: string;
type: 'fill' | 'outlined';
color: string;
startX: string;
startY: string;
endX: string;
endY: string;
}
function HappyWave({ target, token }: HappyWaveProps) {
const prefixCls = 'happy-wave';
const dotPrefixCls = `${prefixCls}-dot`;
const targetPrefixCls = `${prefixCls}-target`;
const [keys, setKeys] = React.useState<number[] | null>(null);
const [hiddenCount, setHiddenCount] = React.useState(0);
const [dots, setDots] = React.useState<DotInfo[] | null>(null);
const [left, setLeft] = React.useState(0);
const [top, setTop] = React.useState(0);
const [width, setWidth] = React.useState(0);
const [height, setHeight] = React.useState(0);
const [, , hashId] = token;
const [, globalToken, hashId] = token;
useWaveStyle(token);
// ========================= Dots =========================
React.useEffect(() => {
if (keys && keys.length) {
setKeys([]);
}
}, [keys]);
React.useEffect(() => {
const id = raf(() => {
const rect = target.getBoundingClientRect();
setLeft(rect.left);
setTop(rect.top);
setWidth(rect.width);
setHeight(rect.height);
setLeft(rect.left + rect.width / 2);
setTop(rect.top + rect.height / 2);
setDots([]);
// Delay to start dot motion
setTimeout(() => {
setKeys(new Array(DOT_COUNT).fill(null).map((_, index) => index + 1));
setDots(
new Array(DOT_COUNT).fill(null).map((_, index) => {
const rotate: number = 360 / DOT_COUNT;
const startAngle: number = rotate * index;
const endAngle: number = rotate * (index + 1);
const randomAngle = Math.random() * (endAngle - startAngle) + startAngle;
const minSize = Math.min(rect.width, rect.height);
const maxSize = Math.max(rect.width, rect.height);
// Get start XY (Which should align the rect edge)
const startX = Math.cos((startAngle * Math.PI) / 180) * minSize;
const startY = Math.sin((startAngle * Math.PI) / 180) * minSize;
// Get end XY
const dist = Math.random() * 30 + maxSize / 2;
const endX = Math.cos((randomAngle * Math.PI) / 180) * dist;
const endY = Math.sin((randomAngle * Math.PI) / 180) * dist;
return {
key: index + 1,
startX: `${startX}px`,
startY: `${startY}px`,
endX: `${endX}px`,
endY: `${endY}px`,
size: `${Math.random() * 4 + 8}px`,
type: Math.random() > 0.6 ? 'outlined' : 'fill',
color:
Math.random() > 0.5 ? globalToken.colorPrimary : globalToken.colorPrimaryBgHover,
};
}),
);
}, 50);
target.className += ` ${targetPrefixCls}`;
@ -59,12 +92,6 @@ function HappyWave({ target, token }: HappyWaveProps) {
};
}, []);
const onDotVisibleChange = (visible: boolean) => {
if (!visible) {
setHiddenCount((cnt) => cnt + 1);
}
};
// ======================== Clean =========================
React.useEffect(() => {
const id = setTimeout(() => {
@ -77,7 +104,7 @@ function HappyWave({ target, token }: HappyWaveProps) {
}, []);
// ======================== Render ========================
if (!keys) {
if (!dots) {
return null;
}
@ -87,38 +114,49 @@ function HappyWave({ target, token }: HappyWaveProps) {
style={{
left,
top,
width,
height,
}}
>
<CSSMotionList keys={keys} motionAppear={false} motionLeave motionName="happy-in-out">
{({ className: motionCls, key }) => {
<CSSMotionList component={false} keys={dots} motionAppear motionName="happy-in-out">
{({
className: motionCls,
style: motionStyle,
key,
startX,
startY,
endX,
endY,
size,
type,
color,
}) => {
const name = `${dotPrefixCls}-${key}`;
const dotCls = classNames(dotPrefixCls, motionCls, name);
return <div className={dotCls} />;
const dotStyle: Record<string, string> = {
[`--start-x`]: startX,
[`--start-y`]: startY,
[`--end-x`]: endX,
[`--end-y`]: endY,
[`--size`]: size,
};
if (type === 'fill') {
dotStyle['--background'] = color;
} else {
dotStyle['--border'] = `1px solid ${color}`;
}
return (
<div
className={dotCls}
style={{
...motionStyle,
...dotStyle,
}}
/>
);
}}
</CSSMotionList>
{/* {keys.map((key) => {
const name = `${dotPrefixCls}-${key}`;
return (
<CSSMotion
key={name}
motionAppear={false}
motionLeave
motionName="happy-in-out"
onVisibleChanged={onDotVisibleChange}
>
{({ className: motionCls }) => {
const dotCls = classNames(dotPrefixCls, motionCls, name);
return <div className={dotCls} />;
}}
</CSSMotion>
);
})} */}
</div>
);
}

Loading…
Cancel
Save