mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-04 03:21:04 +08:00
feat(web): Typewriter 优化(修复 undefined、矩阵绿样式、降低速度)并更新启动指令为 README 前端开发流程
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user