GameCanvas
Interactive HTML5 Canvas component for building games and interactive visualizations. It provides a sandboxed JavaScript execution environment with a game loop, keyboard input handling, score tracking, and high‑score persistence.
GameCanvas
Interactive HTML5 Canvas component for building games and interactive visualizations. It provides a sandboxed JavaScript execution environment with a game loop, keyboard input handling, score tracking, and high‑score persistence.
Use Cases
- Classic arcade games (Snake, Pong, Breakout, Tetris)
- Puzzle games (Memory match, sliding puzzles, pattern games)
- Reaction and reflex games (Whack-a-mole, speed tests)
- Educational games (Math challenges, typing practice)
- Simple platformers and maze games
- Interactive data visualizations
- Drawing/painting applications
- Physics simulations
- Particle effects and animations
- Mini-games for engagement on landing pages
Properties
title
Game title displayed above the canvas. Creates a header for the game. Type: string.
Tip: Keep to 2-3 words maximum. Name should indicate the game type.
width
Canvas width in pixels. Determines the playable area width. Type: number. Default: 400.
Tip: 400x400 works great for Snake, Tetris, puzzle games; 600x400 for Pong, Breakout, side‑scrollers; keep under 400 for best mobile experience.
height
Canvas height in pixels. Determines the playable area height. Type: number. Default: 400.
Tip: 400x400 for most classic games; 300x500 for Tetris‑style games; often best to keep height equal to or less than width.
gameCode
JavaScript code that implements the game logic. Runs in a SANDBOXED environment — NO document, window, setInterval, setTimeout, fetch, or DOM APIs are available. You MUST use the provided game API (onInit, onFrame, ctx, canvas, state, keys, etc.). Type: string. (required)
backgroundColor
Canvas background color. Sets the base color of the game area. Type: string. Default: #0f0f23.
Tip: Use dark colors (#0f0f23, #1a1a2e) for arcade/retro feel; use light colors (#f8f9fa, #ffffff) for casual games; match the app’s backgroundColor for cohesive design.
borderColor
Canvas border color. Creates a frame around the game area. Type: string. Default: #4ecca3.
Tip: Use app’s accentColor or primaryColor; ensure good contrast with backgroundColor.
borderRadius
Canvas border radius for rounded corners. Type: string. Default: 8px.
Tip: Use 0px for sharp retro arcade feel; use 8px‑16px for modern rounded look.
titleColor
Color of the game title text. Type: string. Default: #4ecca3.
textColor
Color of score display and control hints text. Type: string. Default: #eeeeee.
accentColor
Accent color for score values, buttons, and highlights. Type: string. Default: #4ecca3.
showScore
Whether to display current score above the canvas. Type: boolean. Default: true.
showHighScore
Whether to display high score (persisted to localStorage). Type: boolean. Default: true.
scoreLabel
Label text for the score display. Type: string. Default: Score.
highScoreKey
localStorage key for high score. Auto‑generated from title if not specified. Type: string.
Tip: Usually leave blank – will auto‑generate from title; set custom key to share scores across pages.
showControls
Whether to show keyboard control hints below the canvas. Type: boolean. Default: true.
controlsText
Text describing how to control the game. Type: string. Default: Arrow Keys or WASD to move. Space to pause.
showMobileControls
Whether to show touch control buttons on mobile devices. Type: boolean. Default: true.
Best Practices
- NEVER use document, window, setInterval, setTimeout, or any DOM APIs - they are not available in the sandbox
- NEVER call canvas.getContext('2d') - ctx is already provided and ready to use
- Always initialize game state in onInit() callback
- Use onFrame() for game loop - it provides deltaTime for smooth animation
- Use onRestart() to reset game state when player restarts
- Call gameOver() when player loses to show restart overlay
- Use setHighScore() to persist best scores to localStorage
- Use the state object to store all game data (persists across frames)
- Use keys object for input (up, down, left, right, space) - NOT addEventListener
- Keep game logic simple - complex games may have performance issues
- Match colors (backgroundColor, borderColor, accentColor) to app theme
- Set appropriate canvas dimensions for the game type (400x400 default works well)
Common Mistakes
Using document.getElementById, document.addEventListener, or any DOM API
Why it's a problem: SANDBOX: document is NOT available. Game code runs in an isolated Function with no DOM access.
Fix: Use the provided API only: ctx and canvas are already available. Use keys object for input, onInit/onFrame/onRestart for lifecycle.
Using window.onload, window.addEventListener, or window.requestAnimationFrame
Why it's a problem: SANDBOX: window is NOT available. The game runtime manages the animation frame loop for you.
Fix: Use onInit() for startup code, onFrame(deltaTime) for the game loop, and keys object for input.
Using setInterval or setTimeout for the game loop
Why it's a problem: SANDBOX: setInterval/setTimeout are NOT available. Multiple intervals also stack up causing bugs.
Fix: Use onFrame(function(deltaTime) {...}) for the game loop - it’s called every animation frame automatically.
Calling canvas.getContext('2d') to get the drawing context
Why it's a problem: ctx is ALREADY provided and ready to use. Redeclaring it can cause scope conflicts.
Fix: Just use ctx directly: ctx.fillRect(...), ctx.fillStyle = '...', etc.
Writing vanilla JavaScript game code instead of using the GameCanvas API
Why it's a problem: GameCanvas provides a sandboxed runtime. Vanilla JS patterns (DOM manipulation, event listeners, timers) will silently fail.
Fix: Structure code as: onInit() for setup, onFrame(dt) for update‑render loop, keys for input, state for data, setScore/gameOver for game management.
Not using onInit() to initialize state
Why it's a problem: State may be undefined, causing errors on first frame
Fix: Always initialize ALL game state variables in onInit() callback
Forgetting to call gameOver() when game ends
Why it's a problem: Game continues running, player can’t restart
Fix: Call gameOver('Game Over!') when lose condition is met
Not using deltaTime for movement
Why it's a problem: Game speed varies based on frame rate, inconsistent experience
Fix: Multiply movement by deltaTime: state.x += speed * deltaTime
Storing game state outside the state object
Why it's a problem: Variables may be lost between executions or not persist correctly
Fix: Store ALL game data in state object: state.snake = [...], state.score = 0
Not matching colors to app theme
Why it's a problem: Game looks out of place, jarring visual experience
Fix: Set backgroundColor, borderColor, accentColor to match app’s theme
Using context, context.queryName, context.setField, context.save() inside gameCode
Why it's a problem: SANDBOX: context (page query/data-binding system) is NOT available. GameCanvas cannot read from or write to data tables. Will crash with ReferenceError.
Fix: Use the built-in setScore()/setHighScore() for scoring (persisted to localStorage). Do NOT add page-level queries for GameCanvas pages.
Using document.createElement, document.body.appendChild, document.getElementById, document.querySelector, or any DOM manipulation inside gameCode
Why it's a problem: Creating DOM elements injects rogue HTML outside the canvas into the page body, breaking page layout (buttons/inputs appear below the footer).
Fix: GameCanvas has built-in UI: showScore/showHighScore props for scoring display, controlsText for instructions, showMessage() for notifications, onRestart callback for reset. Do NOT create HTML buttons/inputs/toggles — use only canvas drawing (ctx) for in‑game UI.