feat: add glowing effect to active player's pieces
All checks were successful
Deploy c4 / deploy (push) Successful in 42s

Pulsing box-shadow on the current turn's placed pieces makes the
turn state visible directly on the board rather than only in the
status banner.
This commit is contained in:
Ryan Hamamura
2026-02-13 12:34:19 -10:00
parent c541ba56d4
commit 968c2cdb61
3 changed files with 43 additions and 2 deletions

View File

@@ -53,7 +53,17 @@
.cell { width: 48px; height: 48px; border-radius: 50%; background: #556; transition: background 0.2s; } .cell { width: 48px; height: 48px; border-radius: 50%; background: #556; transition: background 0.2s; }
.cell.red { background: #4a2a3a; } .cell.red { background: #4a2a3a; }
.cell.yellow { background: #2a4545; } .cell.yellow { background: #2a4545; }
.cell.red.active-turn { animation: glow-red 1.5s ease-in-out infinite alternate; }
.cell.yellow.active-turn { animation: glow-yellow 1.5s ease-in-out infinite alternate; }
.cell.winning { animation: pulse 0.5s ease-in-out infinite alternate; } .cell.winning { animation: pulse 0.5s ease-in-out infinite alternate; }
@keyframes glow-red {
from { box-shadow: 0 0 4px rgba(74, 42, 58, 0.3); }
to { box-shadow: 0 0 12px rgba(74, 42, 58, 0.7); }
}
@keyframes glow-yellow {
from { box-shadow: 0 0 4px rgba(42, 69, 69, 0.3); }
to { box-shadow: 0 0 12px rgba(42, 69, 69, 0.7); }
}
@keyframes pulse { @keyframes pulse {
from { transform: scale(1); box-shadow: 0 0 4px rgba(0,0,0,0.15); } from { transform: scale(1); box-shadow: 0 0 4px rgba(0,0,0,0.15); }
to { transform: scale(1.03); box-shadow: 0 0 8px rgba(0,0,0,0.25); } to { transform: scale(1.03); box-shadow: 0 0 8px rgba(0,0,0,0.25); }

View File

@@ -1560,9 +1560,31 @@
.cell.yellow { .cell.yellow {
background: #2a4545; background: #2a4545;
} }
.cell.red.active-turn {
animation: glow-red 1.5s ease-in-out infinite alternate;
}
.cell.yellow.active-turn {
animation: glow-yellow 1.5s ease-in-out infinite alternate;
}
.cell.winning { .cell.winning {
animation: pulse 0.5s ease-in-out infinite alternate; animation: pulse 0.5s ease-in-out infinite alternate;
} }
@keyframes glow-red {
from {
box-shadow: 0 0 4px rgba(74, 42, 58, 0.3);
}
to {
box-shadow: 0 0 12px rgba(74, 42, 58, 0.7);
}
}
@keyframes glow-yellow {
from {
box-shadow: 0 0 4px rgba(42, 69, 69, 0.3);
}
to {
box-shadow: 0 0 12px rgba(42, 69, 69, 0.7);
}
}
@keyframes pulse { @keyframes pulse {
from { from {
transform: scale(1); transform: scale(1);

View File

@@ -11,12 +11,18 @@ type ColumnClickFn func(col int) h.H
func BoardComponent(g *game.Game, columnClick ColumnClickFn, myColor int) h.H { func BoardComponent(g *game.Game, columnClick ColumnClickFn, myColor int) h.H {
var cols []h.H var cols []h.H
activeTurn := 0
if g.Status == game.StatusInProgress {
activeTurn = g.CurrentTurn
}
for col := 0; col < 7; col++ { for col := 0; col < 7; col++ {
var cells []h.H var cells []h.H
for row := 0; row < 6; row++ { for row := 0; row < 6; row++ {
cellColor := g.Board[row][col] cellColor := g.Board[row][col]
isWinning := g.IsWinningCell(row, col) isWinning := g.IsWinningCell(row, col)
cells = append(cells, Cell(cellColor, isWinning)) isActiveTurn := cellColor != 0 && cellColor == activeTurn
cells = append(cells, Cell(cellColor, isWinning, isActiveTurn))
} }
// Column is clickable only if it's player's turn and game is in progress // Column is clickable only if it's player's turn and game is in progress
@@ -45,7 +51,7 @@ func Column(colIdx int, cells []h.H, columnClick ColumnClickFn, canClick bool) h
return h.Div(attrs...) return h.Div(attrs...)
} }
func Cell(color int, isWinning bool) h.H { func Cell(color int, isWinning, isActiveTurn bool) h.H {
class := "cell" class := "cell"
switch color { switch color {
case 1: case 1:
@@ -56,5 +62,8 @@ func Cell(color int, isWinning bool) h.H {
if isWinning { if isWinning {
class += " winning" class += " winning"
} }
if isActiveTurn {
class += " active-turn"
}
return h.Div(h.Class(class)) return h.Div(h.Class(class))
} }