-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflashcards.html
More file actions
201 lines (192 loc) · 10.5 KB
/
flashcards.html
File metadata and controls
201 lines (192 loc) · 10.5 KB
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>闪卡学习 - 期末突击</title>
<script src="https://cdn.tailwindcss.com"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<style>
[x-cloak] { display: none !important; }
.flip-card {
perspective: 1000px;
}
.flip-card-inner {
transition: transform 0.6s;
transform-style: preserve-3d;
}
.flip-card.flipped .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front, .flip-card-back {
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.flip-card-back {
transform: rotateY(180deg);
}
</style>
</head>
<body class="bg-gray-50 min-h-screen" x-data="flashcardApp()">
<nav class="bg-white shadow-md sticky top-0 z-50">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16">
<div class="flex items-center">
<a href="index.html" class="text-xl sm:text-2xl font-bold text-indigo-600">期末突击</a>
<span class="hidden sm:block ml-3 text-gray-500">|</span>
<span class="hidden sm:block ml-3 text-gray-700">闪卡学习</span>
</div>
<div class="hidden sm:flex items-center space-x-4">
<a href="index.html" class="text-gray-700 hover:text-indigo-600 px-3 py-2 rounded-md text-sm font-medium">首页</a>
<a href="flashcards.html" class="text-indigo-600 px-3 py-2 rounded-md text-sm font-medium">闪卡学习</a>
<a href="concepts.html" class="text-gray-700 hover:text-indigo-600 px-3 py-2 rounded-md text-sm font-medium">核心概念</a>
<a href="unlock.html" class="bg-indigo-600 text-white px-4 py-2 rounded-md text-sm font-medium hover:bg-indigo-700">解锁全部</a>
</div>
<div class="sm:hidden flex items-center">
<button @click="mobileMenuOpen = !mobileMenuOpen" class="text-gray-700 hover:text-indigo-600 p-2">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path x-show="!mobileMenuOpen" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
<path x-show="mobileMenuOpen" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
</div>
</div>
<div x-show="mobileMenuOpen" x-transition class="sm:hidden bg-white border-t">
<div class="px-4 py-3 space-y-2">
<a href="index.html" @click="mobileMenuOpen = false" class="block text-gray-700 hover:text-indigo-600 px-3 py-2 rounded-md text-sm font-medium">首页</a>
<a href="flashcards.html" @click="mobileMenuOpen = false" class="block text-indigo-600 px-3 py-2 rounded-md text-sm font-medium">闪卡学习</a>
<a href="concepts.html" @click="mobileMenuOpen = false" class="block text-gray-700 hover:text-indigo-600 px-3 py-2 rounded-md text-sm font-medium">核心概念</a>
<a href="unlock.html" @click="mobileMenuOpen = false" class="block bg-indigo-600 text-white px-3 py-2 rounded-md text-sm font-medium">解锁全部</a>
</div>
</div>
</nav>
<main class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-8 sm:py-12">
<div class="text-center mb-6 sm:mb-8">
<h1 class="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">闪卡学习</h1>
<p class="text-gray-600 text-sm sm:text-base" x-text="`进度:${currentIndex + 1} / ${totalCards}`"></p>
</div>
<div x-show="!isUnlocked && currentIndex >= 10" class="bg-yellow-50 border-l-4 border-yellow-400 p-4 mb-6">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-yellow-400" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd"/>
</svg>
</div>
<div class="ml-3">
<p class="text-sm text-yellow-700">
免费版仅显示前10个闪卡,<a href="unlock.html" class="font-medium underline hover:text-yellow-800">立即解锁全部67个闪卡</a>
</p>
</div>
</div>
</div>
<div class="flex justify-center mb-6 sm:mb-8">
<div class="flip-card w-full h-64 sm:h-80 cursor-pointer"
:class="{ 'flipped': isFlipped }"
@click="toggleFlip()">
<div class="flip-card-inner relative w-full h-full">
<div class="flip-card-front absolute w-full h-full bg-white rounded-xl shadow-lg p-4 sm:p-8 flex flex-col justify-center items-center">
<div class="text-xs sm:text-sm text-indigo-600 mb-2 sm:mb-4">问题</div>
<div class="text-base sm:text-xl text-gray-800 text-center px-2" x-text="currentCard.question"></div>
<div class="mt-4 sm:mt-6 text-xs sm:text-sm text-gray-500">点击翻转查看答案</div>
</div>
<div class="flip-card-back absolute w-full h-full bg-gradient-to-br from-indigo-500 to-purple-600 rounded-xl shadow-lg p-4 sm:p-8 flex flex-col justify-center items-center text-white">
<div class="text-xs sm:text-sm mb-2 sm:mb-4 opacity-80">答案</div>
<div class="text-base sm:text-xl text-center px-2" x-text="currentCard.answer"></div>
<div class="mt-4 sm:mt-6 text-xs sm:text-sm opacity-80">点击翻转查看问题</div>
</div>
</div>
</div>
</div>
<div class="flex justify-center space-x-2 sm:space-x-4 mb-6 sm:mb-8">
<button @click="previousCard()"
:disabled="currentIndex === 0"
class="px-4 sm:px-6 py-2 sm:py-3 bg-white border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors text-sm sm:text-base">
← 上一张
</button>
<button @click="shuffleCards()"
class="px-4 sm:px-6 py-2 sm:py-3 bg-white border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 transition-colors text-sm sm:text-base">
随机打乱
</button>
<button @click="nextCard()"
:disabled="currentIndex >= totalCards - 1"
class="px-4 sm:px-6 py-2 sm:py-3 bg-white border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors text-sm sm:text-base">
下一张 →
</button>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-lg font-semibold mb-4">学习进度</h3>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="bg-indigo-600 h-2.5 rounded-full transition-all duration-300"
:style="`width: ${((currentIndex + 1) / totalCards) * 100}%`"></div>
</div>
<div class="mt-2 text-sm text-gray-600" x-text="`已完成 ${currentIndex + 1} / ${totalCards} 张闪卡`"></div>
</div>
<div class="mt-8 text-center">
<p class="text-gray-600 mb-4">快捷键提示</p>
<div class="flex justify-center space-x-4 text-sm text-gray-500">
<span>← → 切换闪卡</span>
<span>空格 翻转</span>
<span>S 打乱</span>
</div>
</div>
</main>
<footer class="bg-gray-800 text-white mt-12 py-8">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<p class="text-gray-400">© 2024 期末突击 - 高效复习,轻松应对期末考试</p>
</div>
</footer>
<script src="js/data.js"></script>
<script>
function flashcardApp() {
return {
cards: flashcardsData,
currentIndex: 0,
isFlipped: false,
isUnlocked: isUnlocked(),
get totalCards() {
return this.isUnlocked ? this.cards.length : 10;
},
get currentCard() {
return this.cards[this.currentIndex];
},
toggleFlip() {
this.isFlipped = !this.isFlipped;
},
nextCard() {
if (this.currentIndex < this.totalCards - 1) {
this.currentIndex++;
this.isFlipped = false;
}
},
previousCard() {
if (this.currentIndex > 0) {
this.currentIndex--;
this.isFlipped = false;
}
},
shuffleCards() {
for (let i = this.cards.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[this.cards[i], this.cards[j]] = [this.cards[j], this.cards[i]];
}
this.currentIndex = 0;
this.isFlipped = false;
}
}
}
document.addEventListener('keydown', function(e) {
if (e.key === 'ArrowRight') {
Alpine.store('flashcardApp')?.nextCard();
} else if (e.key === 'ArrowLeft') {
Alpine.store('flashcardApp')?.previousCard();
} else if (e.key === ' ') {
e.preventDefault();
Alpine.store('flashcardApp')?.toggleFlip();
} else if (e.key === 's' || e.key === 'S') {
Alpine.store('flashcardApp')?.shuffleCards();
}
});
</script>
</body>
</html>