二货爱吃白萝卜
1 year ago
committed by
GitHub
16 changed files with 288 additions and 41 deletions
@ -0,0 +1,119 @@ |
|||
// 用于 color.md 中的颜色对比
|
|||
import React from 'react'; |
|||
import classNames from 'classnames'; |
|||
import { theme, Space } from 'antd'; |
|||
import { TinyColor } from '@ctrl/tinycolor'; |
|||
import tokenMeta from 'antd/es/version/token-meta.json'; |
|||
import { createStyles } from 'antd-style'; |
|||
import useLocale from '../../../hooks/useLocale'; |
|||
|
|||
const useStyle = createStyles(({ token, css }) => { |
|||
const height = token.controlHeightLG; |
|||
const dotSize = height / 5; |
|||
|
|||
return { |
|||
container: css` |
|||
background: #fff; |
|||
border-radius: ${token.borderRadiusLG}px; |
|||
overflow: hidden; |
|||
`,
|
|||
|
|||
row: css` |
|||
display: flex; |
|||
align-items: center; |
|||
`,
|
|||
|
|||
col: css` |
|||
flex: 1 1 33%; |
|||
height: ${height}px; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
|
|||
border-right: 1px solid rgba(0, 0, 0, 0.1); |
|||
`,
|
|||
|
|||
colDark: css` |
|||
background: #000; |
|||
color: #fff; |
|||
`,
|
|||
|
|||
dot: css` |
|||
border-radius: 100%; |
|||
width: ${dotSize}px; |
|||
height: ${dotSize}px; |
|||
background: #000; |
|||
box-shadow: 0 0 0 1px rgba(150, 150, 150, 0.25); |
|||
`,
|
|||
|
|||
dotColor: css` |
|||
width: ${token.fontSize * 6}px; |
|||
white-space: nowrap; |
|||
`,
|
|||
}; |
|||
}); |
|||
|
|||
function color2Rgba(color: string) { |
|||
return `#${new TinyColor(color).toHex8().toUpperCase()}`; |
|||
} |
|||
|
|||
interface ColorCircleProps { |
|||
color?: string; |
|||
} |
|||
|
|||
function ColorCircle({ color }: ColorCircleProps) { |
|||
const { styles } = useStyle(); |
|||
|
|||
return ( |
|||
<Space size={4}> |
|||
<div className={styles.dot} style={{ background: color }} /> |
|||
<div className={styles.dotColor}>{color}</div> |
|||
</Space> |
|||
); |
|||
} |
|||
|
|||
export interface TokenCompareProps { |
|||
tokenNames?: string; |
|||
} |
|||
|
|||
export default function TokenCompare(props: TokenCompareProps) { |
|||
const { tokenNames = '' } = props; |
|||
const [, lang] = useLocale({}); |
|||
const { styles } = useStyle(); |
|||
|
|||
const tokenList = React.useMemo(() => { |
|||
const list = tokenNames.split('|'); |
|||
|
|||
const lightTokens = theme.getDesignToken(); |
|||
const darkTokens = theme.getDesignToken({ |
|||
algorithm: theme.darkAlgorithm, |
|||
}); |
|||
|
|||
return list.map((tokenName) => { |
|||
const meta = tokenMeta.global[tokenName]; |
|||
const name = lang === 'cn' ? meta.name : meta.nameEn; |
|||
|
|||
return { |
|||
name: name.replace('颜色', '').replace('色', '').replace('Color', '').trim(), |
|||
light: color2Rgba(lightTokens[tokenName]), |
|||
dark: color2Rgba(darkTokens[tokenName]), |
|||
}; |
|||
}); |
|||
}, [tokenNames]); |
|||
|
|||
return ( |
|||
<div className={styles.container}> |
|||
{tokenList.map((data) => ( |
|||
<div key={data.name} className={styles.row}> |
|||
<div className={styles.col}>{data.name}</div> |
|||
<div className={styles.col}> |
|||
<ColorCircle color={data.light} /> |
|||
</div> |
|||
<div className={classNames(styles.col, styles.colDark)}> |
|||
<ColorCircle color={data.dark} /> |
|||
</div> |
|||
</div> |
|||
))} |
|||
</div> |
|||
); |
|||
} |
@ -0,0 +1,77 @@ |
|||
import React from 'react'; |
|||
import { createStyles, css } from 'antd-style'; |
|||
import classNames from 'classnames'; |
|||
import { PlayCircleFilled, PauseCircleFilled } from '@ant-design/icons'; |
|||
|
|||
const useStyles = createStyles(({ cx, token }) => { |
|||
const play = css` |
|||
position: absolute; |
|||
right: ${token.paddingLG}px; |
|||
bottom: ${token.paddingLG}px; |
|||
font-size: 64px; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
color: rgba(0, 0, 0, 0.65); |
|||
opacity: 0; |
|||
transition: opacity ${token.motionDurationSlow}; |
|||
`;
|
|||
|
|||
return { |
|||
container: css` |
|||
position: relative; |
|||
`,
|
|||
|
|||
holder: css` |
|||
position: relative; |
|||
cursor: pointer; |
|||
|
|||
&:hover { |
|||
.${cx(play)} { |
|||
opacity: 1; |
|||
} |
|||
} |
|||
`,
|
|||
|
|||
video: css` |
|||
width: 100%; |
|||
`,
|
|||
|
|||
play, |
|||
}; |
|||
}); |
|||
|
|||
export default function VideoPlayer({ |
|||
className, |
|||
...restProps |
|||
}: React.HtmlHTMLAttributes<HTMLVideoElement>) { |
|||
const { styles } = useStyles(); |
|||
const videoRef = React.useRef<HTMLVideoElement>(null); |
|||
const [playing, setPlaying] = React.useState(false); |
|||
|
|||
React.useEffect(() => { |
|||
if (playing) { |
|||
videoRef.current?.play(); |
|||
} else { |
|||
videoRef.current?.pause(); |
|||
} |
|||
}, [playing]); |
|||
|
|||
return ( |
|||
<div |
|||
className={classNames(styles.container, className)} |
|||
tabIndex={0} |
|||
role="button" |
|||
title="play or pause" |
|||
onClick={() => { |
|||
setPlaying(!playing); |
|||
}} |
|||
> |
|||
<div className={classNames(styles.holder)}> |
|||
<video ref={videoRef} className={styles.video} muted loop {...restProps} /> |
|||
|
|||
<div className={styles.play}>{playing ? <PauseCircleFilled /> : <PlayCircleFilled />}</div> |
|||
</div> |
|||
</div> |
|||
); |
|||
} |
Loading…
Reference in new issue