二货爱吃白萝卜
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