Spaces:
Sleeping
Sleeping
File size: 8,611 Bytes
1bd2bb8 df1ba4a 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 df1ba4a 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 9fb8186 1bd2bb8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | <!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>程序员打字练习 | Code Typing Practice</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;700&display=swap" rel="stylesheet">
<style>
body {
font-family: 'Fira Code', monospace;
}
.cursor {
border-right: 2px solid #3b82f6;
animation: blink 1s step-end infinite;
}
@keyframes blink {
50% { border-color: transparent; }
}
.no-ligatures {
font-variant-ligatures: none;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: #1e293b;
}
::-webkit-scrollbar-thumb {
background: #475569;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #64748b;
}
</style>
</head>
<body class="bg-slate-900 text-slate-200 min-h-screen flex flex-col items-center justify-center p-4 selection:bg-blue-500/30">
<!-- Header -->
<header class="w-full max-w-5xl flex flex-col md:flex-row justify-between items-center mb-6 gap-4">
<div class="flex items-baseline gap-2">
<h1 class="text-2xl font-bold text-blue-400 tracking-tight">程序员打字练习</h1>
<span class="text-slate-500 text-xs font-mono">v1.2</span>
</div>
<div class="flex flex-wrap items-center gap-4 text-sm">
<!-- Language Selector -->
<div class="flex items-center gap-2 bg-slate-800 px-3 py-1.5 rounded border border-slate-700">
<label for="lang-select" class="text-slate-400 text-xs uppercase">Language</label>
<select id="lang-select" class="bg-transparent text-yellow-400 font-bold focus:outline-none cursor-pointer">
<option value="All">All</option>
<!-- Populated by JS -->
</select>
</div>
<!-- Sound Toggle -->
<button id="sound-toggle" class="flex items-center gap-2 px-3 py-1.5 rounded border border-slate-700 bg-slate-800 hover:bg-slate-700 transition-colors" title="开关音效">
<span id="sound-icon">🔊</span>
</button>
<!-- Custom Code Button -->
<button id="custom-code-btn" class="px-3 py-1.5 rounded border border-slate-700 bg-slate-800 hover:bg-slate-700 transition-colors text-slate-300">
自定义代码
</button>
</div>
</header>
<!-- Main Typing Area -->
<main class="w-full max-w-5xl relative bg-slate-800/80 backdrop-blur-sm rounded-xl shadow-2xl overflow-hidden border border-slate-700/50 ring-1 ring-white/5">
<!-- Stats Bar -->
<div class="bg-slate-900/50 p-4 flex flex-wrap justify-around border-b border-slate-700/50 gap-4">
<div class="text-center min-w-[80px]">
<div class="text-[10px] text-slate-500 uppercase tracking-widest font-bold">WPM</div>
<div id="wpm" class="text-3xl font-bold text-emerald-400 tabular-nums">0</div>
</div>
<div class="text-center min-w-[80px]">
<div class="text-[10px] text-slate-500 uppercase tracking-widest font-bold">Accuracy</div>
<div id="accuracy" class="text-3xl font-bold text-blue-400 tabular-nums">100%</div>
</div>
<div class="text-center min-w-[80px]">
<div class="text-[10px] text-slate-500 uppercase tracking-widest font-bold">Progress</div>
<div id="progress" class="text-3xl font-bold text-purple-400 tabular-nums">0%</div>
</div>
<!-- Best WPM (Local Storage) -->
<div class="text-center min-w-[80px] border-l border-slate-700 pl-4 hidden md:block">
<div class="text-[10px] text-slate-500 uppercase tracking-widest font-bold">Today's Best</div>
<div id="best-wpm" class="text-3xl font-bold text-yellow-500/80 tabular-nums">-</div>
</div>
</div>
<!-- Code Container -->
<div class="relative group">
<!-- Hidden Input -->
<input type="text" id="hidden-input" class="absolute opacity-0 top-0 left-0 h-full w-full cursor-default z-0" autocomplete="off" spellcheck="false">
<!-- Code Display -->
<div id="code-container" class="h-[400px] overflow-y-auto p-8 relative z-0 scroll-smooth">
<div id="code-display" class="whitespace-pre no-ligatures select-none text-lg leading-relaxed text-slate-500" onclick="document.getElementById('hidden-input').focus()">
<div class="flex items-center justify-center h-full animate-pulse">Loading snippets...</div>
</div>
</div>
<!-- Focus Hint -->
<div id="focus-hint" class="absolute top-4 right-6 text-xs text-slate-500 bg-slate-900/80 px-2 py-1 rounded opacity-0 transition-opacity duration-300 pointer-events-none">
Click to focus
</div>
<!-- Result Overlay -->
<div id="result-overlay" class="absolute inset-0 bg-slate-900/95 flex flex-col items-center justify-center hidden z-20 backdrop-blur-md transition-all duration-300">
<div class="text-center transform transition-all duration-500 scale-100">
<h2 class="text-5xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-blue-400 to-emerald-400 mb-8">Completed!</h2>
<div class="grid grid-cols-2 gap-12 mb-10">
<div class="text-center">
<div class="text-sm text-slate-400 uppercase tracking-widest mb-2">WPM</div>
<div id="final-wpm" class="text-6xl font-bold text-emerald-400 drop-shadow-lg">0</div>
</div>
<div class="text-center">
<div class="text-sm text-slate-400 uppercase tracking-widest mb-2">Accuracy</div>
<div id="final-accuracy" class="text-6xl font-bold text-blue-400 drop-shadow-lg">0%</div>
</div>
</div>
<div class="flex gap-4 justify-center">
<button id="restart-btn" class="px-8 py-3 bg-blue-600 hover:bg-blue-500 text-white rounded-lg font-bold transition-all transform hover:scale-105 shadow-lg shadow-blue-900/50">
Again (Enter)
</button>
</div>
</div>
</div>
</div>
</main>
<!-- Footer -->
<footer class="mt-8 text-slate-500 text-xs text-center">
<p class="mb-2">
<span class="inline-block bg-slate-800 px-2 py-1 rounded border border-slate-700 mx-1">Tab</span> 重置
<span class="mx-2">|</span>
<span class="inline-block bg-slate-800 px-2 py-1 rounded border border-slate-700 mx-1">Space</span> 缩进
</p>
<p class="opacity-50">推荐使用 Chrome / Edge 浏览器获得最佳体验</p>
</footer>
<!-- Custom Code Modal -->
<div id="custom-modal" class="fixed inset-0 bg-black/80 flex items-center justify-center hidden z-50 backdrop-blur-sm">
<div class="bg-slate-800 p-6 rounded-xl shadow-2xl w-full max-w-2xl border border-slate-700">
<h3 class="text-xl font-bold text-white mb-4">粘贴自定义代码</h3>
<textarea id="custom-input" class="w-full h-64 bg-slate-900 text-slate-300 p-4 rounded-lg font-mono text-sm border border-slate-700 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 outline-none resize-none" placeholder="在此处粘贴代码..."></textarea>
<div class="flex justify-end gap-4 mt-4">
<button id="custom-cancel" class="px-4 py-2 text-slate-400 hover:text-white transition-colors">取消</button>
<button id="custom-confirm" class="px-6 py-2 bg-blue-600 hover:bg-blue-500 text-white rounded-lg font-bold transition-colors">开始练习</button>
</div>
</div>
</div>
<script src="/static/script.js"></script>
</body>
</html>
|