优化时钟布局和响应式设计
- 将样式选择器移到页面顶部 - 添加响应式时钟尺寸,根据浏览器宽度自适应 - 修复样式选择器与时钟数字的重叠问题 - 优化 CSS 布局结构 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a3d4012064
commit
ec06bdc29f
@ -5,6 +5,7 @@
|
|||||||
## 项目概述
|
## 项目概述
|
||||||
|
|
||||||
一个精简的 React + TypeScript + Vite 入门项目。
|
一个精简的 React + TypeScript + Vite 入门项目。
|
||||||
|
主要功能是在页面上显示数码风格的时钟。
|
||||||
|
|
||||||
- **Node 版本**: v24.14.0(在 `.nvmrc` 中指定)
|
- **Node 版本**: v24.14.0(在 `.nvmrc` 中指定)
|
||||||
- **包管理器**: npm
|
- **包管理器**: npm
|
||||||
@ -66,3 +67,8 @@ src/
|
|||||||
## 构建输出
|
## 构建输出
|
||||||
|
|
||||||
生产构建输出到 `dist/` 目录(ESLint 会忽略该目录)。
|
生产构建输出到 `dist/` 目录(ESLint 会忽略该目录)。
|
||||||
|
|
||||||
|
## 本地存储
|
||||||
|
|
||||||
|
本地存储使用localStorage,用于保存用户设置。
|
||||||
|
|
||||||
|
|||||||
44
src/App.css
44
src/App.css
@ -9,25 +9,9 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
gap: 40px;
|
padding-top: 40px;
|
||||||
}
|
box-sizing: border-box;
|
||||||
|
|
||||||
.clock-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Digital clock style (default) */
|
|
||||||
.digital-clock {
|
|
||||||
font-family: 'DSEG7', monospace;
|
|
||||||
font-size: 15vw;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #fff;
|
|
||||||
text-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
|
|
||||||
letter-spacing: 0.1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style selector */
|
/* Style selector */
|
||||||
@ -38,6 +22,30 @@
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
background-color: rgba(255, 255, 255, 0.05);
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
z-index: 10;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-bottom: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Digital clock style (default) */
|
||||||
|
.digital-clock {
|
||||||
|
font-family: 'DSEG7', monospace;
|
||||||
|
font-size: clamp(48px, 15vw, 180px);
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 0 0 20px rgba(255, 255, 255, 0.5);
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.style-button {
|
.style-button {
|
||||||
|
|||||||
32
src/App.tsx
32
src/App.tsx
@ -16,6 +16,7 @@ function DigitalClock({ time }: { time: string }) {
|
|||||||
function App() {
|
function App() {
|
||||||
const [time, setTime] = useState(new Date())
|
const [time, setTime] = useState(new Date())
|
||||||
const [clockStyle, setClockStyle] = useState<ClockStyle>('digital')
|
const [clockStyle, setClockStyle] = useState<ClockStyle>('digital')
|
||||||
|
const [clockSize, setClockSize] = useState(120)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setInterval(() => {
|
const timer = setInterval(() => {
|
||||||
@ -24,14 +25,33 @@ function App() {
|
|||||||
return () => clearInterval(timer)
|
return () => clearInterval(timer)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
// Responsive clock size
|
||||||
|
useEffect(() => {
|
||||||
|
const updateSize = () => {
|
||||||
|
const width = window.innerWidth
|
||||||
|
if (width < 480) {
|
||||||
|
setClockSize(Math.floor(width / 8))
|
||||||
|
} else if (width < 768) {
|
||||||
|
setClockSize(Math.floor(width / 7))
|
||||||
|
} else if (width < 1024) {
|
||||||
|
setClockSize(100)
|
||||||
|
} else {
|
||||||
|
setClockSize(120)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateSize()
|
||||||
|
window.addEventListener('resize', updateSize)
|
||||||
|
return () => window.removeEventListener('resize', updateSize)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const timeString = `${String(time.getHours()).padStart(2, '0')}:${String(time.getMinutes()).padStart(2, '0')}:${String(time.getSeconds()).padStart(2, '0')}`
|
const timeString = `${String(time.getHours()).padStart(2, '0')}:${String(time.getMinutes()).padStart(2, '0')}:${String(time.getSeconds()).padStart(2, '0')}`
|
||||||
|
|
||||||
const renderClock = () => {
|
const renderClock = () => {
|
||||||
switch (clockStyle) {
|
switch (clockStyle) {
|
||||||
case 'flip':
|
case 'flip':
|
||||||
return <FlipClock time={timeString} size={120} />
|
return <FlipClock time={timeString} size={clockSize} />
|
||||||
case 'roll':
|
case 'roll':
|
||||||
return <RollClock time={timeString} size={120} />
|
return <RollClock time={timeString} size={clockSize} />
|
||||||
case 'digital':
|
case 'digital':
|
||||||
default:
|
default:
|
||||||
return <DigitalClock time={timeString} />
|
return <DigitalClock time={timeString} />
|
||||||
@ -40,10 +60,6 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app">
|
<div className="app">
|
||||||
<div className="clock-container">
|
|
||||||
{renderClock()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="style-selector">
|
<div className="style-selector">
|
||||||
<button
|
<button
|
||||||
className={`style-button ${clockStyle === 'digital' ? 'active' : ''}`}
|
className={`style-button ${clockStyle === 'digital' ? 'active' : ''}`}
|
||||||
@ -64,6 +80,10 @@ function App() {
|
|||||||
滚动
|
滚动
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="clock-container">
|
||||||
|
{renderClock()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user