feat(web): Typewriter 优化(修复 undefined、矩阵绿样式、降低速度)并更新启动指令为 README 前端开发流程

This commit is contained in:
Ember
2025-11-01 23:53:17 +08:00
parent daba1bc113
commit 4dfe6626fc
2 changed files with 21 additions and 59 deletions

View File

@@ -381,24 +381,6 @@ export function LandingPage() {
/>
</motion.div>
<FloatingCard
delay={0.7}
position={{ bottom: '-6', left: '-6' }}
color='yellow'
>
<div
className='text-2xl font-bold'
style={{ color: 'var(--brand-yellow)' }}
>
24/7
</div>
<div
className='text-xs'
style={{ color: 'var(--text-secondary)' }}
>
</div>
</FloatingCard>
</motion.div>
</div>
</div>
@@ -519,15 +501,16 @@ export function LandingPage() {
<Typewriter
lines={[
'$ git clone https://github.com/tinkle-community/nofx',
'$ docker compose up -d',
'🚀 NOFX 已启动',
'✓ AI 代理运行中',
'✓ 交易所已连接',
'✓ 策略已激活',
'$ cd nofx/web',
'$ npm install',
'$ npm run dev',
'🚀 前端已启动 http://localhost:3000',
'✓ 就绪',
]}
typingSpeed={24}
lineDelay={350}
typingSpeed={55}
lineDelay={700}
className='text-sm font-mono'
style={{ color: '#00FF41', textShadow: '0 0 6px rgba(0,255,65,0.6)' }}
/>
</motion.div>
</motion.div>
@@ -940,33 +923,6 @@ export function LandingPage() {
)
}
// Helper Components
function FloatingCard({ children, delay, position, color }: any) {
return (
<motion.div
className={`absolute rounded-xl px-4 py-3 backdrop-blur-xl z-20`}
style={{
background: 'rgba(30, 35, 41, 0.9)',
border: `1px solid ${
color === 'green'
? 'rgba(14, 203, 129, 0.3)'
: 'rgba(240, 185, 11, 0.3)'
}`,
...Object.keys(position).reduce((acc: any, key) => {
acc[key] = position[key] + 'rem'
return acc
}, {}),
}}
initial={{ opacity: 0, scale: 0 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay, type: 'spring', stiffness: 260, damping: 20 }}
whileHover={{ scale: 1.1, rotate: 5 }}
>
{children}
</motion.div>
)
}
function AnimatedSection({
children,
id,

View File

@@ -5,15 +5,17 @@ interface TypewriterProps {
typingSpeed?: number // 毫秒/字符
lineDelay?: number // 每行结束的额外等待
className?: string
style?: React.CSSProperties
}
export default function Typewriter({
lines,
typingSpeed = 25,
lineDelay = 400,
typingSpeed = 50,
lineDelay = 600,
className,
style,
}: TypewriterProps) {
const [text, setText] = useState('')
const [typedLines, setTypedLines] = useState<string[]>([''])
const [showCursor, setShowCursor] = useState(true)
const lineIndexRef = useRef(0)
const charIndexRef = useRef(0)
@@ -24,15 +26,19 @@ export default function Typewriter({
function typeNext() {
const currentLine = lines[lineIndexRef.current] ?? ''
if (charIndexRef.current < currentLine.length) {
setText((t) => t + currentLine[charIndexRef.current])
setTypedLines((prev) => {
const next = [...prev]
next[next.length - 1] = (next[next.length - 1] || '') + currentLine[charIndexRef.current]
return next
})
charIndexRef.current += 1
timerRef.current = window.setTimeout(typeNext, typingSpeed)
} else {
// 行结束
if (lineIndexRef.current < lines.length - 1) {
setText((t) => t + '\n')
lineIndexRef.current += 1
charIndexRef.current = 0
setTypedLines((prev) => [...prev, ''])
timerRef.current = window.setTimeout(typeNext, lineDelay)
} else {
// 最后一行输入完毕
@@ -55,8 +61,8 @@ export default function Typewriter({
}, [lines, typingSpeed, lineDelay])
return (
<pre className={className}>
{text}
<pre className={className} style={style}>
{typedLines.join('\n')}
<span style={{ opacity: showCursor ? 1 : 0 }}> </span>
</pre>
)