Every frame, the game clears the 400×400 canvas, draws a dark background grid, draws the pulsing food item, and draws each snake segment as a rounded rectangle with an optional glow. The food pulse animation and shadow intensities respectDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/ac-unefm/snake-game/llms.txt
Use this file to discover all available pages before exploring further.
prefers-reduced-motion — when motion reduction is requested, values are fixed so nothing on screen blinks or oscillates.
Canvas setup
The canvas element is declared in HTML with fixed intrinsic dimensions:draw() — main render function
draw() is called once per tick, after update() has advanced the game state:
- Fill background — a solid
#111111rectangle clears the previous frame. drawGrid()— overlays the faint grid lines.drawFood()— draws the pulsing food circle.snake.forEach(drawSegment)— iterates over every snake cell; index0is passed asisHead = true.
drawGrid()
drawGrid() renders a 20×20 cell grid over the background:
strokeStyle is set to COLORS.grid (#161616), which is only slightly lighter than the #111111 background, producing a subtle grid that is visible without being distracting. lineWidth of 0.5 keeps the lines thin and crisp on high-DPI displays.
drawFood()
The food is rendered as a circle with a glow that pulses in and out using a sine wave:
pulseoscillates between 0 and 1 via0.5 + 0.5 * Math.sin(Date.now() / 200). WhenreducedMotionistrue,pulseis fixed at0.5— the midpoint — so neither radius nor glow changes between frames.fr(food radius) ranges fromGRID_SIZE * 0.28(≈ 5.6 px) toGRID_SIZE * 0.36(≈ 7.2 px), making the food gently breathe.shadowBlurranges from8to14, intensifying the glow in sync with the radius. When reduced motion is active it stays at8.ctx.save()/ctx.restore()isolate theshadowColorandshadowBlurstate so the glow does not bleed onto the grid lines or snake segments drawn in the same frame.
drawSegment(seg, isHead)
Each snake cell is drawn as a rounded rectangle constructed manually with arcTo:
- Padding —
padis1for the head and2for body segments. A smaller padding on the head makes it slightly larger than the body, giving a visual cue that it is the leading cell. - Corner radius —
r = 4px produces a softly rounded rectangle. arcTopath — each corner useslineToto approach the corner point, thenarcToto arc around it. The path traces all four sides clockwise: top → right → bottom → left.- Head glow —
shadowColorandshadowBlur = 12are set only whenisHeadistrue. Body segments have no shadow, which reduces visual noise and slightly improves rendering performance. ctx.save()/ctx.restore()— used on every segment so that head shadow state does not carry forward to the next body segment.
Color palette
| Element | Color | Variable |
|---|---|---|
| Snake head | #a855f7 | COLORS.head |
| Snake body | #7e22ce | COLORS.body |
| Food | #f87171 | COLORS.food |
| Grid lines | #161616 | COLORS.grid |
| Background | #111111 | CSS --color-surface |
prefers-reduced-motion
The When
reducedMotion constant is set once at startup using:reducedMotion is true:- The food
pulsevalue is fixed at0.5— the circle neither expands nor contracts between frames. shadowBluron the food is fixed at8— the glow intensity does not change.
@media (prefers-reduced-motion: reduce) block that removes transition declarations from interactive elements (skip link, session dots, buttons, footer links).