From 374238025cc57bdb240a2fc40a56647f087059e0 Mon Sep 17 00:00:00 2001 From: sonicmaster123 <179001180@qq.com> Date: Thu, 16 Apr 2026 22:12:53 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=95=AA?= =?UTF-8?q?=E8=8C=84=E9=92=9F=E8=AE=A1=E6=97=B6=E5=99=A8=E5=9F=BA=E7=A1=80?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现番茄钟计时器的基本功能,包括: - 创建HTML结构展示计时器界面 - 添加JavaScript实现计时器逻辑(开始、暂停、重置) - 编写CSS样式美化界面 --- index.html | 21 ++++++++++++++ script.js | 55 ++++++++++++++++++++++++++++++++++++ style.css | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 index.html create mode 100644 script.js create mode 100644 style.css diff --git a/index.html b/index.html new file mode 100644 index 0000000..b1ad993 --- /dev/null +++ b/index.html @@ -0,0 +1,21 @@ + + + + + + 番茄钟计时器 + + + +
+

番茄钟

+
25:00
+
+ + + +
+
+ + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..7aa1064 --- /dev/null +++ b/script.js @@ -0,0 +1,55 @@ +const timerDisplay = document.getElementById('timer'); +const startBtn = document.getElementById('startBtn'); +const pauseBtn = document.getElementById('pauseBtn'); +const resetBtn = document.getElementById('resetBtn'); + +const WORK_MINUTES = 25; +let totalSeconds = WORK_MINUTES * 60; +let timerInterval = null; +let isRunning = false; + +function formatTime(seconds) { + const mins = Math.floor(seconds / 60); + const secs = seconds % 60; + return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; +} + +function updateDisplay() { + timerDisplay.textContent = formatTime(totalSeconds); +} + +function startTimer() { + if (isRunning) return; + + isRunning = true; + timerInterval = setInterval(() => { + if (totalSeconds > 0) { + totalSeconds--; + updateDisplay(); + } else { + clearInterval(timerInterval); + isRunning = false; + alert('时间到'); + } + }, 1000); +} + +function pauseTimer() { + if (!isRunning) return; + + clearInterval(timerInterval); + isRunning = false; +} + +function resetTimer() { + clearInterval(timerInterval); + isRunning = false; + totalSeconds = WORK_MINUTES * 60; + updateDisplay(); +} + +startBtn.addEventListener('click', startTimer); +pauseBtn.addEventListener('click', pauseTimer); +resetBtn.addEventListener('click', resetTimer); + +updateDisplay(); diff --git a/style.css b/style.css new file mode 100644 index 0000000..996189f --- /dev/null +++ b/style.css @@ -0,0 +1,82 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: center; +} + +.container { + background: white; + padding: 40px 60px; + border-radius: 20px; + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); + text-align: center; +} + +h1 { + color: #333; + font-size: 2.5em; + margin-bottom: 30px; + font-weight: 300; +} + +.timer { + font-size: 6em; + font-weight: 100; + color: #667eea; + margin: 40px 0; + letter-spacing: 5px; + font-variant-numeric: tabular-nums; +} + +.controls { + display: flex; + gap: 15px; + justify-content: center; +} + +.btn { + padding: 15px 40px; + font-size: 1.1em; + border: none; + border-radius: 50px; + cursor: pointer; + transition: all 0.3s ease; + font-weight: 500; +} + +.btn-start { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; +} + +.btn-start:hover { + transform: translateY(-2px); + box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4); +} + +.btn-pause { + background: #f0f0f0; + color: #666; +} + +.btn-pause:hover { + background: #e0e0e0; +} + +.btn-reset { + background: #f0f0f0; + color: #666; +} + +.btn-reset:hover { + background: #e0e0e0; +} From fd10bbe4ec11fe361708614b5be3973446c5779f Mon Sep 17 00:00:00 2001 From: sonicmaster123 <179001180@qq.com> Date: Thu, 16 Apr 2026 22:22:45 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C/=E4=BC=91=E6=81=AF=E6=A8=A1=E5=BC=8F=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 实现工作模式和休息模式的切换功能,包括: - 添加模式切换按钮和状态指示器 - 不同模式下的界面样式变化 - 计时器在不同模式下的时间设置 --- index.html | 3 ++- script.js | 44 +++++++++++++++++++++++++++++++++++++++++++- style.css | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 92 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index b1ad993..e51c312 100644 --- a/index.html +++ b/index.html @@ -8,9 +8,10 @@
-

番茄钟

+
工作模式
25:00
+ diff --git a/script.js b/script.js index 7aa1064..eeb591c 100644 --- a/script.js +++ b/script.js @@ -1,9 +1,13 @@ const timerDisplay = document.getElementById('timer'); +const modeIndicator = document.getElementById('modeIndicator'); +const modeBtn = document.getElementById('modeBtn'); const startBtn = document.getElementById('startBtn'); const pauseBtn = document.getElementById('pauseBtn'); const resetBtn = document.getElementById('resetBtn'); const WORK_MINUTES = 25; +const BREAK_MINUTES = 5; +let isWorkMode = true; let totalSeconds = WORK_MINUTES * 60; let timerInterval = null; let isRunning = false; @@ -18,6 +22,36 @@ function updateDisplay() { timerDisplay.textContent = formatTime(totalSeconds); } +function updateModeUI() { + if (isWorkMode) { + document.body.classList.remove('break-mode'); + modeIndicator.textContent = '工作模式'; + modeBtn.textContent = '切换到休息'; + } else { + document.body.classList.add('break-mode'); + modeIndicator.textContent = '休息模式'; + modeBtn.textContent = '切换到工作'; + } +} + +function toggleMode() { + if (isRunning) { + clearInterval(timerInterval); + isRunning = false; + } + + isWorkMode = !isWorkMode; + + if (isWorkMode) { + totalSeconds = WORK_MINUTES * 60; + } else { + totalSeconds = BREAK_MINUTES * 60; + } + + updateModeUI(); + updateDisplay(); +} + function startTimer() { if (isRunning) return; @@ -44,12 +78,20 @@ function pauseTimer() { function resetTimer() { clearInterval(timerInterval); isRunning = false; - totalSeconds = WORK_MINUTES * 60; + + if (isWorkMode) { + totalSeconds = WORK_MINUTES * 60; + } else { + totalSeconds = BREAK_MINUTES * 60; + } + updateDisplay(); } +modeBtn.addEventListener('click', toggleMode); startBtn.addEventListener('click', startTimer); pauseBtn.addEventListener('click', pauseTimer); resetBtn.addEventListener('click', resetTimer); +updateModeUI(); updateDisplay(); diff --git a/style.css b/style.css index 996189f..2584b7d 100644 --- a/style.css +++ b/style.css @@ -11,6 +11,11 @@ body { display: flex; justify-content: center; align-items: center; + transition: background 0.5s ease; +} + +body.break-mode { + background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); } .container { @@ -21,11 +26,16 @@ body { text-align: center; } -h1 { - color: #333; - font-size: 2.5em; - margin-bottom: 30px; - font-weight: 300; +.mode-indicator { + font-size: 1.5em; + font-weight: 500; + color: #667eea; + margin-bottom: 20px; + transition: color 0.5s ease; +} + +body.break-mode .mode-indicator { + color: #11998e; } .timer { @@ -35,12 +45,18 @@ h1 { margin: 40px 0; letter-spacing: 5px; font-variant-numeric: tabular-nums; + transition: color 0.5s ease; +} + +body.break-mode .timer { + color: #11998e; } .controls { display: flex; gap: 15px; justify-content: center; + flex-wrap: wrap; } .btn { @@ -53,16 +69,42 @@ h1 { font-weight: 500; } +.btn-mode { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; +} + +body.break-mode .btn-mode { + background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); +} + +.btn-mode:hover { + transform: translateY(-2px); + box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4); +} + +body.break-mode .btn-mode:hover { + box-shadow: 0 5px 20px rgba(17, 153, 142, 0.4); +} + .btn-start { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; } +body.break-mode .btn-start { + background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); +} + .btn-start:hover { transform: translateY(-2px); box-shadow: 0 5px 20px rgba(102, 126, 234, 0.4); } +body.break-mode .btn-start:hover { + box-shadow: 0 5px 20px rgba(17, 153, 142, 0.4); +} + .btn-pause { background: #f0f0f0; color: #666; From 6171cd2570afa06ed7ff1ff07dea847df3b1f0d8 Mon Sep 17 00:00:00 2001 From: sonicmaster123 <179001180@qq.com> Date: Thu, 16 Apr 2026 22:37:03 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E7=A6=81=E7=94=A8=E7=8A=B6=E6=80=81=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E5=92=8C=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加按钮禁用时的样式效果,并在计时器结束时禁用所有控制按钮以防止误操作 --- script.js | 9 +++++++++ style.css | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/script.js b/script.js index eeb591c..b40bc6a 100644 --- a/script.js +++ b/script.js @@ -34,6 +34,13 @@ function updateModeUI() { } } +function setButtonsDisabled(disabled) { + modeBtn.disabled = disabled; + startBtn.disabled = disabled; + pauseBtn.disabled = disabled; + resetBtn.disabled = disabled; +} + function toggleMode() { if (isRunning) { clearInterval(timerInterval); @@ -63,7 +70,9 @@ function startTimer() { } else { clearInterval(timerInterval); isRunning = false; + setButtonsDisabled(true); alert('时间到'); + setButtonsDisabled(false); } }, 1000); } diff --git a/style.css b/style.css index 2584b7d..3cf117e 100644 --- a/style.css +++ b/style.css @@ -69,6 +69,13 @@ body.break-mode .timer { font-weight: 500; } +.btn:disabled { + opacity: 0.5; + cursor: not-allowed; + transform: none !important; + box-shadow: none !important; +} + .btn-mode { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white;