Skip to content

Commit 4f4de4b

Browse files
committed
add preset button
1 parent 2550c37 commit 4f4de4b

1 file changed

Lines changed: 69 additions & 20 deletions

File tree

src/components/GameSetup.vue

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@
1717
<div class="setup-section">
1818
<h3>棋盘</h3>
1919
<div class="option-group">
20-
<label class="option-card" :class="{ active: boardMode === 'standard' }">
20+
<label class="option-btn" :class="{ active: boardMode === 'standard' }">
2121
<input v-model="boardMode" type="radio" value="standard" />
2222
<img :src="iconClassic" alt="" class="card-icon" />
2323
<span>标准棋盘</span>
2424
</label>
25-
<label class="option-card" :class="{ active: boardMode === 'chess960' }">
25+
<label class="option-btn" :class="{ active: boardMode === 'chess960' }">
2626
<input v-model="boardMode" type="radio" value="chess960" />
2727
<img :src="iconChess960" alt="" class="card-icon" />
2828
<span>Chess960</span>
2929
</label>
30-
<label class="option-card" :class="{ active: boardMode === 'custom' }">
30+
<label class="option-btn" :class="{ active: boardMode === 'custom' }">
3131
<input v-model="boardMode" type="radio" value="custom" />
3232
<img :src="iconCustom" alt="" class="card-icon" />
3333
<span>自定义棋盘</span>
@@ -52,13 +52,27 @@
5252
<input v-model.number="incrementSeconds" type="range" min="0" max="60" step="1" />
5353
<strong>{{ incrementSeconds }} 秒</strong>
5454
</label>
55+
56+
<!-- 快捷棋钟组合按钮 -->
57+
<div class="preset-clock-group">
58+
<button
59+
v-for="preset in presetClocks"
60+
:key="preset.label"
61+
type="button"
62+
class="option-btn preset-btn"
63+
:class="{ active: isPresetActive(preset.minutes, preset.increment) }"
64+
@click="applyPreset(preset.minutes, preset.increment)"
65+
>
66+
{{ preset.label }}
67+
</button>
68+
</div>
5569
</div>
5670

5771
<!-- 强度设置(仅人机对局) -->
5872
<div v-if="gameMode === 'ai'" class="setup-section">
5973
<h3>强度</h3>
6074
<div class="option-group">
61-
<label v-for="level in 5" :key="level" class="option-card difficulty-card"
75+
<label v-for="level in 5" :key="level" class="option-btn difficulty-card"
6276
:class="{ active: difficulty === level }">
6377
<input v-model="difficulty" type="radio" :value="level" />
6478
<span>{{ level }}</span>
@@ -70,19 +84,19 @@
7084
<div v-if="gameMode === 'ai'" class="setup-section">
7185
<h3>AI 风格</h3>
7286
<div class="option-group">
73-
<label class="option-card" :class="{ active: aiStyle === 'balanced' }">
87+
<label class="option-btn" :class="{ active: aiStyle === 'balanced' }">
7488
<input v-model="aiStyle" type="radio" value="balanced" />
7589
<span>均衡</span>
7690
</label>
77-
<label class="option-card" :class="{ active: aiStyle === 'aggressive' }">
91+
<label class="option-btn" :class="{ active: aiStyle === 'aggressive' }">
7892
<input v-model="aiStyle" type="radio" value="aggressive" />
7993
<span>进攻</span>
8094
</label>
81-
<label class="option-card" :class="{ active: aiStyle === 'defensive' }">
95+
<label class="option-btn" :class="{ active: aiStyle === 'defensive' }">
8296
<input v-model="aiStyle" type="radio" value="defensive" />
8397
<span>防守</span>
8498
</label>
85-
<label class="option-card" :class="{ active: aiStyle === 'unpredictable' }">
99+
<label class="option-btn" :class="{ active: aiStyle === 'unpredictable' }">
86100
<input v-model="aiStyle" type="radio" value="unpredictable" />
87101
<span>出其不意</span>
88102
</label>
@@ -92,17 +106,17 @@
92106
<div v-if="gameMode === 'ai'" class="setup-section">
93107
<h3>执棋方</h3>
94108
<div class="option-group">
95-
<label class="option-card starter-card" :class="{ active: starter === 'black' }">
109+
<label class="option-btn starter-card" :class="{ active: starter === 'black' }">
96110
<input v-model="starter" type="radio" value="black" />
97111
<img :src="kingBlackIcon" alt="" class="starter-icon" />
98112
<span>黑方</span>
99113
</label>
100-
<label class="option-card starter-card" :class="{ active: starter === 'random' }">
114+
<label class="option-btn starter-card" :class="{ active: starter === 'random' }">
101115
<input v-model="starter" type="radio" value="random" />
102116
<img :src="kingRandomIcon" alt="" class="starter-icon" />
103117
<span>随机</span>
104118
</label>
105-
<label class="option-card starter-card" :class="{ active: starter === 'white' }">
119+
<label class="option-btn starter-card" :class="{ active: starter === 'white' }">
106120
<input v-model="starter" type="radio" value="white" />
107121
<img :src="kingWhiteIcon" alt="" class="starter-icon" />
108122
<span>白方</span>
@@ -159,6 +173,32 @@ const incrementSeconds = ref(0)
159173
const starter = ref<'black' | 'random' | 'white'>('white')
160174
const errorMessage = ref('')
161175
176+
// ============================================================
177+
// 常用棋钟预设组合
178+
// ============================================================
179+
const presetClocks = [
180+
{ label: '1+0', minutes: 1, increment: 0 },
181+
{ label: '2+1', minutes: 2, increment: 1 },
182+
{ label: '3+0', minutes: 3, increment: 0 },
183+
{ label: '3+2', minutes: 3, increment: 2 },
184+
{ label: '5+0', minutes: 5, increment: 0 },
185+
{ label: '5+3', minutes: 5, increment: 3 },
186+
{ label: '10+0', minutes: 10, increment: 0 },
187+
{ label: '10+5', minutes: 10, increment: 5 },
188+
{ label: '15+10', minutes: 15, increment: 10 },
189+
{ label: '30+0', minutes: 30, increment: 0 },
190+
{ label: '30+20', minutes: 30, increment: 20 },
191+
]
192+
193+
const applyPreset = (minutes: number, increment: number) => {
194+
timeMinutes.value = minutes
195+
incrementSeconds.value = increment
196+
}
197+
198+
const isPresetActive = (minutes: number, increment: number) => {
199+
return timeMinutes.value === minutes && incrementSeconds.value === increment
200+
}
201+
162202
const startSetup = (mode: 'ai' | 'human') => {
163203
gameMode.value = mode
164204
screen.value = 'setup'
@@ -391,7 +431,7 @@ const handleStart = () => {
391431
min-width: 0;
392432
}
393433
394-
.option-card {
434+
.option-btn {
395435
display: inline-flex;
396436
align-items: center;
397437
gap: 6px;
@@ -405,7 +445,7 @@ const handleStart = () => {
405445
}
406446
407447
/* 隐藏原生的单选框圆点 */
408-
.option-card input[type="radio"] {
448+
.option-btn input[type="radio"] {
409449
display: none;
410450
}
411451
@@ -418,7 +458,7 @@ const handleStart = () => {
418458
font-weight: 600;
419459
}
420460
421-
.option-card.active {
461+
.option-btn.active {
422462
border-color: var(--color-surface-border);
423463
background: var(--color-surface-border);
424464
color: var(--color-text-on-primary);
@@ -456,12 +496,6 @@ const handleStart = () => {
456496
/* 默认(大窗口)布局:采用 Grid 确保多行之间对齐齐平 */
457497
.slider-row {
458498
display: grid;
459-
/*
460-
100px: 左侧标签区域
461-
1fr: 滑动条占据剩余中间空间
462-
100px: 右侧数值区域(右对齐)
463-
16px: 控件与两侧的间距(包含滑动条与时间文本间的距离)
464-
*/
465499
grid-template-columns: 100px 1fr 100px;
466500
gap: 16px;
467501
align-items: center;
@@ -477,6 +511,21 @@ const handleStart = () => {
477511
white-space: nowrap;
478512
}
479513
514+
/* 棋钟快捷选项样式 */
515+
.preset-clock-group {
516+
display: flex;
517+
flex-wrap: wrap;
518+
gap: 8px;
519+
margin-top: 8px;
520+
}
521+
522+
.preset-btn {
523+
background-color: transparent;
524+
padding: 2px 4px;
525+
font-size: 0.8rem;
526+
font-family: 'Unifont', system-ui, -apple-system, sans-serif;
527+
}
528+
480529
@media (max-width: 480px) {
481530
.slider-row {
482531
display: flex;

0 commit comments

Comments
 (0)