Skip to content

Commit 61a10fa

Browse files
committed
Winning combo is now blinking
1 parent d28e3cd commit 61a10fa

File tree

3 files changed

+41
-12
lines changed

3 files changed

+41
-12
lines changed

css/animations.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ dialog input.error {
1919
}
2020
}
2121

22-
.blinking-text {
23-
animation: blink 1s infinite;
22+
.blinking {
23+
animation: blink 0.5s infinite;
2424
}
2525

2626
@keyframes blink {

css/style.css

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ main {
111111
background-color: black;
112112
}
113113

114+
.square svg {
115+
transition: transform 1s ease-in-out;
116+
}
117+
118+
.win svg {
119+
color: red;
120+
}
121+
122+
.irrelevant svg {
123+
opacity: 0.5;
124+
}
125+
114126
.scores {
115127
display: grid;
116128
grid-template-columns: repeat(3, 1fr);

js/game.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export default class Game {
4343

4444
this.#board.forEach(square => {
4545
square.innerHTML = '';
46+
square.classList.remove('win', 'irrelevant');
4647
const handler = this.#listeners.get(square);
4748
square.removeEventListener('click', handler);
4849
});
@@ -102,19 +103,32 @@ export default class Game {
102103
const [a, b, c] = combo;
103104

104105
if (this.#state[a] && this.#state[a] === this.#state[b] && this.#state[a] === this.#state[c]) {
105-
return this.#state[a];
106+
return combo;
106107
}
107108
}
108109

109110
// No empty squares without a winner => tie
110111
if (!this.#state.includes('')) {
111-
return 'T';
112+
return [];
112113
}
113114

114115
return null;
115116
}
116117

117-
#endRound(winner) {
118+
#endRound(winningCombo) {
119+
const winner = winningCombo.length === 0 ? 'T' : this.#state[winningCombo[0]];
120+
121+
this.#board.forEach((square, index) => {
122+
if (winningCombo.includes(index)) {
123+
square.classList.add('win');
124+
square.querySelector('svg').classList.add('blinking');
125+
setTimeout(() => { square.querySelector('svg').classList.remove('blinking') }, 1500);
126+
}
127+
else {
128+
square.classList.add('irrelevant');
129+
}
130+
})
131+
118132
this.#end = true;
119133
this.#saveScore(winner);
120134
this.#updateScore(winner);
@@ -136,26 +150,29 @@ export default class Game {
136150
if (winner === 'T') {
137151
this.#ties++;
138152
this.#tiesTag.textContent = this.#ties;
139-
this.#tiesTag.classList.add('blinking-text');
140-
setTimeout(() => { this.#tiesTag.classList.remove('blinking-text'); }, 2000);
153+
this.#tiesTag.classList.add('blinking');
154+
setTimeout(() => { this.#tiesTag.classList.remove('blinking'); }, 1500);
141155
} else if (winner === 'X') {
142156
this.#xWins++;
143157
this.#xWinsTag.textContent = this.#xWins;
144-
this.#xWinsTag.classList.add('blinking-text');
145-
setTimeout(() => { this.#xWinsTag.classList.remove('blinking-text'); }, 2000);
158+
this.#xWinsTag.classList.add('blinking');
159+
setTimeout(() => { this.#xWinsTag.classList.remove('blinking'); }, 1500);
146160
} else if (winner === 'O') {
147161
this.#oWins++;
148162
this.#oWinsTag.textContent = this.#oWins;
149-
this.#oWinsTag.classList.add('blinking-text');
150-
setTimeout(() => { this.#oWinsTag.classList.remove('blinking-text'); }, 2000);
163+
this.#oWinsTag.classList.add('blinking');
164+
setTimeout(() => { this.#oWinsTag.classList.remove('blinking'); }, 1500);
151165
}
152166
}
153167

154168
#resetBoard() {
155169
// Even number of rounds => next round is odd => X starts (and vice versa)
156170
this.#onTurn = (this.#ties + this.#xWins + this.#oWins) % 2 === 0 ? 'X' : 'O';
157171
this.#state = ['', '', '', '', '', '', '', '', ''];
158-
this.#board.forEach(square => square.innerHTML = '');
172+
this.#board.forEach(square => {
173+
square.innerHTML = '';
174+
square.classList.remove('win', 'irrelevant');
175+
});
159176
}
160177

161178
#prepareAssets() {

0 commit comments

Comments
 (0)