feat(web): connect quick share flow
Signed-off-by: JustMe <mr.toing@outlook.com>
This commit is contained in:
1 parent
53768a195d
commit
e02e024605
138 files changed
+10614
No files matched your search
@@ -0,0 +1,61 @@
|
||||
import { useEffect, useState, type AnimationEvent } from 'react';
|
||||
import styles from './Splash.module.css';
|
||||
|
||||
/** 单线手写 WebDrop,逐笔画出。每个字母一条路径,按序号错开 */
|
||||
const STROKES = [
|
||||
'M4 14 L14 58 L24 30 L34 58 L44 14',
|
||||
'M52 42 H76 C76 28 66 26 60 31 C50 38 53 58 63 58 C69 59 74 56 77 52',
|
||||
'M88 8 L88 58 M88 46 C92 34 106 36 106 47 C106 59 92 62 88 52',
|
||||
'M120 14 L120 58 M120 14 C156 12 160 58 120 58',
|
||||
'M172 30 L172 58 M172 42 C176 31 186 29 192 33',
|
||||
'M204 46 C204 33 222 33 222 46 C222 59 204 59 204 46',
|
||||
'M236 32 L236 74 M236 46 C240 34 256 36 256 48 C256 60 242 64 236 54',
|
||||
];
|
||||
|
||||
const reduced = () => matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
interface Props {
|
||||
ready: boolean;
|
||||
onDone: () => void;
|
||||
}
|
||||
|
||||
export function Splash({ ready, onDone }: Props) {
|
||||
const [animDone, setAnimDone] = useState(reduced);
|
||||
const [skipped, setSkipped] = useState(false);
|
||||
const leaving = skipped || (animDone && ready);
|
||||
|
||||
useEffect(() => {
|
||||
const skip = () => setSkipped(true);
|
||||
window.addEventListener('keydown', skip);
|
||||
return () => window.removeEventListener('keydown', skip);
|
||||
}, []);
|
||||
|
||||
function onEnd(e: AnimationEvent) {
|
||||
if (e.animationName.includes('draw') && e.target instanceof SVGElement && e.target.dataset.last) setAnimDone(true);
|
||||
if (e.animationName.includes('leave') && e.target === e.currentTarget) onDone();
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`${styles.splash} ${leaving ? styles.leaving : ''}`}
|
||||
onClick={() => setSkipped(true)}
|
||||
onAnimationEnd={onEnd}
|
||||
role="status"
|
||||
aria-label="加载中"
|
||||
>
|
||||
<svg viewBox="0 0 262 82" className={styles.word} aria-hidden="true">
|
||||
{STROKES.map((d, i) => (
|
||||
<path
|
||||
key={d}
|
||||
d={d}
|
||||
pathLength={1}
|
||||
className={styles.stroke}
|
||||
style={{ '--i': i } as React.CSSProperties}
|
||||
data-last={i === STROKES.length - 1 ? '1' : undefined}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
<p className={styles.hint}>加载中</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user