Skip to content

Commit 7073212

Browse files
Merge pull request steam-bell-92#470 from Bhavikapatel06/fix/global-canvas-getcontext-error
fix: resolve canvas error in game modals
2 parents 608a5d6 + ea0ddcd commit 7073212

3 files changed

Lines changed: 75 additions & 40 deletions

File tree

web-app/js/hero-canvas.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
Fixed: canvas now fills 100% of hero section
44
═══════════════════════════════════════════ */
55
const canvas = document.getElementById('boardCanvas');
6-
const ctx = canvas.getContext('2d');
76

8-
/* Force canvas to fill the hero section absolutely */
7+
if (canvas) {
8+
const ctx = canvas.getContext('2d');
9+
10+
/* Force canvas to fill the hero section absolutely */
911
(function positionCanvas() {
1012
const hero = canvas.closest('.hero-section') || canvas.parentElement;
1113
if (hero && getComputedStyle(hero).position === 'static') {
@@ -289,6 +291,7 @@ function loop() {
289291
tokens.forEach(t => { t.update(); t.draw(); });
290292
drawDice();
291293
requestAnimationFrame(loop);
292-
}
294+
}
293295

294-
loop();
296+
loop();
297+
}

web-app/js/projects.js

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3471,31 +3471,6 @@ function getTowerOfHanoiHTML() {
34713471
`;
34723472
}
34733473

3474-
function initTowerOfHanoi() {
3475-
const canvas = document.getElementById('hanoiCanvas');
3476-
const ctx = canvas.getContext('2d');
3477-
const diskCountInput = document.getElementById('diskCount');
3478-
const solveBtn = document.getElementById('solveBtn');
3479-
const resetBtn = document.getElementById('resetHanoi');
3480-
const moveCountEl = document.getElementById('moveCount');
3481-
const optimalMovesEl = document.getElementById('optimalMoves');
3482-
3483-
let towers = [[], [], []];
3484-
let diskCount = 3;
3485-
let moveCount = 0;
3486-
let isAnimating = false;
3487-
let shouldStop = false;
3488-
3489-
const towerX = [200, 400, 600];
3490-
const baseY = 350;
3491-
const diskHeight = 20;
3492-
const maxDiskWidth = 120;
3493-
const colors = ['#ff6b6b', '#f59e0b', '#10b981', '#06b6d4', '#6366f1', '#8b5cf6', '#ec4899'];
3494-
3495-
function initTowers() {
3496-
towers = [[], [], []];
3497-
moveCount = 0;
3498-
diskCount = parseInt(diskCountInput.value) || 3;
34993474

35003475
//Reset animation state
35013476
isAnimating = false;
@@ -3841,7 +3816,6 @@ function initializeProject(projectName) {
38413816
initializers[projectName]();
38423817
}
38433818
}
3844-
}
38453819

38463820
//Removed Redundant game and project Logics and seperated them to different individual files located at (web-app/js/projects/)
38473821

web-app/js/projects/whack-a-mole.js

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,39 +45,89 @@ function initWhackaMole() {
4545
let timeLeft = 30;
4646
let gameActive = false;
4747
let activeIndex = -1;
48+
let lastActiveIndex = -1;
49+
let lastActiveTime = 0;
4850
let timerId = null;
4951
let moleId = null;
5052

5153
const holes = Array.from({ length: 9 }, (_, index) => {
5254
const button = document.createElement('button');
5355
button.type = 'button';
5456
button.className = 'whack-hole';
57+
button.textContent = '🕳️';
5558
button.setAttribute('aria-label', `Hole ${index + 1}`);
56-
button.addEventListener('click', () => {
57-
if (!gameActive || index !== activeIndex) return;
59+
60+
const handleHit = (e) => {
61+
if (e) e.preventDefault();
62+
if (!gameActive) return;
63+
64+
const isDirectHit = (index === activeIndex);
65+
const isGraceHit = (index === lastActiveIndex && (Date.now() - lastActiveTime) < 150);
66+
67+
if (!isDirectHit && !isGraceHit) return;
68+
5869
score += 1;
5970
scoreEl.textContent = String(score);
60-
messageEl.textContent = 'Hit!';
71+
messageEl.textContent = 'Hit! 🔨';
72+
button.textContent = '💥';
73+
button.classList.remove('active');
74+
75+
// Set to -1 immediately to prevent double hits
76+
activeIndex = -1;
77+
lastActiveIndex = -1;
78+
6179
clearTimeout(moleId);
62-
showMole();
63-
});
80+
moleId = setTimeout(showMole, 250);
81+
};
82+
83+
button.addEventListener('pointerdown', handleHit);
84+
button.addEventListener('click', handleHit);
85+
6486
board.appendChild(button);
6587
return button;
6688
});
6789

6890
function showMole() {
69-
holes.forEach(hole => hole.classList.remove('active'));
70-
activeIndex = Math.floor(Math.random() * holes.length);
91+
if (!gameActive) return;
92+
93+
// Save previous active mole state for grace period
94+
if (activeIndex !== -1) {
95+
lastActiveIndex = activeIndex;
96+
lastActiveTime = Date.now();
97+
}
98+
99+
holes.forEach(hole => {
100+
hole.classList.remove('active');
101+
hole.textContent = '🕳️';
102+
});
103+
104+
// Choose a new hole, ensuring it is different from the current one
105+
let newIndex;
106+
do {
107+
newIndex = Math.floor(Math.random() * holes.length);
108+
} while (newIndex === activeIndex && holes.length > 1);
109+
110+
activeIndex = newIndex;
71111
holes[activeIndex].classList.add('active');
112+
holes[activeIndex].textContent = '🐭';
113+
72114
moleId = setTimeout(showMole, 850);
73115
}
74116

75117
function stopGame(finalMessage) {
76118
gameActive = false;
77119
clearInterval(timerId);
120+
timerId = null;
78121
clearTimeout(moleId);
79-
holes.forEach(hole => hole.classList.remove('active'));
122+
moleId = null;
123+
activeIndex = -1;
124+
lastActiveIndex = -1;
125+
holes.forEach(hole => {
126+
hole.classList.remove('active');
127+
hole.textContent = '🕳️';
128+
});
80129
messageEl.textContent = finalMessage;
130+
startBtn.disabled = false;
81131
}
82132

83133
function startGame() {
@@ -87,29 +137,37 @@ function initWhackaMole() {
87137
scoreEl.textContent = '0';
88138
timeEl.textContent = '30';
89139
messageEl.textContent = 'Go!';
140+
startBtn.disabled = true;
90141
clearInterval(timerId);
91142
clearTimeout(moleId);
92-
showMole();
93143
timerId = setInterval(() => {
94144
timeLeft -= 1;
95145
timeEl.textContent = String(timeLeft);
96146
if (timeLeft <= 0) {
97147
stopGame(`Time! Final score: ${score}`);
98148
}
99149
}, 1000);
150+
showMole();
100151
}
101152

102153
startBtn.addEventListener('click', startGame);
103154
resetBtn.addEventListener('click', () => {
104155
clearInterval(timerId);
156+
timerId = null;
105157
clearTimeout(moleId);
158+
moleId = null;
106159
score = 0;
107160
timeLeft = 30;
108161
gameActive = false;
109162
activeIndex = -1;
110-
holes.forEach(hole => hole.classList.remove('active'));
163+
lastActiveIndex = -1;
164+
holes.forEach(hole => {
165+
hole.classList.remove('active');
166+
hole.textContent = '🕳️';
167+
});
111168
scoreEl.textContent = '0';
112169
timeEl.textContent = '30';
113170
messageEl.textContent = 'Hit the mole when it appears.';
171+
startBtn.disabled = false;
114172
});
115173
}

0 commit comments

Comments
 (0)