
LITECANVAS
Litecanvas is a lightweight HTML5 canvas engine suitable for small web games, prototypes, game jams, animations, creative programming, learning game programming and game design, etc.
⚠️ Warning
This project is still in the "alpha" stage. Break changes may occur frequently. All feedback is welcome and appreciated! For bugs or contribuitions open a issue in our Github Repository.
Hello World
Create a text file named index.html
, put the code below and open it your browser.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/>
<title>Hello Litecanvas</title>
<style>body { margin: 0 }</style>
<script src="https://unpkg.com/litecanvas/dist/dist.dev.js"></script>
</head>
<body>
<script>
// start the engine
litecanvas();
function draw() {
// clear the screen with black (color #0)
cls(0)
// write 'Hello World' in x=0 y=0
text(0, 0, 'Hello World')
}
</script>
</body>
</html>
Basic boilerplate
litecanvas({
loop: {
init, update, draw, resized,
tap, tapping, untap, tapped
}
})
function init(instance) {
// "instance" is the engine instance
// run once before the game starts
}
function update(dt) {
// called at 60 fps by default
// note: "dt" is a fixed deltatime (fps/1000)
}
function draw(canvasContext2d) {
// used to draw your graphics
}
function resized(newScale) {
// called when the canvas is resized
// use W and H to get the new width and height of the canvas
}
function tap(x, y, touchId) {
// called when a tap (click/touch) starts
// equivalent to "mousedown" and "touchstart" browser events
// Notes:
// - "touchId" is used to handle multiple touches
// - each touch has a unique touchId >= 1
// - mouse's touchId always equal to 0 (zero)
}
function untap(x, y, touchId) {
// called when a tap end
// equivalent to "mouseup" and "touchend" browser events
}
function tapping(x, y, touchId) {
// called when a tap moves
// equivalent to "mousemove" and "touchmove" browser events
}
function tapped(x, y, touchId) {
// called when a tap stars and ends in a short time
// equivalent to "click" browser events (only for left mouse clicks)
}
Default Colors

Note: Every time a function asks for a color argument, choose one of these numbers.
Game Configuration
// Initialize the game
litecanvas(settings = {});
// the core game loop callbacks
// if the loop option is null, the engine will uses
// global functions with the same name as the events:
// window.init(), window.update(), window.draw(), etc
settings.loop = {
init: Function?, // (instance) => void
update: Function?, // (dt) => void
draw: Function?, // (ctx) => void
resized: Function?, // (scale) => void
tap: Function?, // (x, y, touchId) => void
untap: Function? // (x, y, touchId) => void
tapping: Function?, // (x, y, touchId) => void
tapped: Function? // (x, y, touchId) => void
}
// the canvas (by default a new canvas is created).
settings.canvas = null
// set the canvas (game screen) size
// if width is null, the canvas fills the entire webpage.
settings.width = null
settings.height = settings.width || null
// Determines whether the canvas should scale to fill the screen,
// but preserving the aspect ratio. Rather than a boolean you
// can pass a number to determine a maximum scale.
settings.autoscale = true
// If `true`, the pixel art images won't look blurry.
// Also, disables canvas built-in antialias.
settings.pixelart = false
// exposes all methods and properties (see below)
// in the global scope
settings.global = true
// set to `false` to disable the default tap handler
// useful to create your own mouse/touch handler
settings.tapEvents = true
// set to `false` to disable the built in keyboard functions
// useful to create your own keyboard handler
settings.keyboardEvents = true
Variables
// the amount of time since the game started
T: number
// the game screen width
W: number
// the game screen height
H: number
// the current mouse's X-position
// or -1 (if the mouse was not used or detected)
MX: number
// the current mouse's Y-position
// or -1 (if the mouse was not used or detected)
MY: number
// Math constants
PI: number // approximately 3.14 radians (180°)
TWO_PI: number // approximately 6.28 radians (360°)
HALF_PI: number // approximately 1.57 radians (90°)
Functions for Drawing
/**
* SHAPES DRAWING-RELATED FUNCTIONS
*/
// clear the canvas
// if color is a number, fill the entire screen with which color
// if null just clear the screen
cls(color: number | null): void
// draw a color-filled rectangle
// radii is for border radius
rectfill(x, y, w, h, color = 0, radii?: number | number[]): void
// draw a outline rectangle
// radii is for border radius
rect(x, y, w, h, color = 0, radii?: number | number[]): void
// draw a color-filled circle
circfill(x, y, r, color = 0): void
// draw a outline circle
circ(x, y, r, color = 0): void
// draw a color-filled ellipse
ovalfill(x, y, rx, ry, color = 0): void
// draw a outline ellipse
oval(x, y, rx, ry, color = 0): void
// draw a line from one point (x1, y1) to another (x2, y2)
line(x1, y1, x2, y2, color = 0): void
// Sets the thickness of lines
linewidth(value: number): void
// Sets the line dash pattern used when drawing lines
linedash(value: number[], ofsset?: number): void
/**
* TEXT DRAWING-RELATED FUNCTIONS
*/
// Draw a text
// style can be "normal", "italic" and/or "bold"
text(x, y, text, color? = 3, style? = 'normal'): void
// Sets the text alignment and baseline
// default values: align = 'start', baseline = 'top'
// see: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign
// see: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline
textalign(align?: string, baseline?: string): void
// Sets the font family for texts
textfont(fontName: string): void
// Sets the font size (default: 18)
textsize(size: number): void
/**
* IMAGE DRAWING-RELATED FUNCTIONS
*/
// draw a image
image(x, y, image: Image|HTMLCanvasElement): void
// create an OffscreenCanvas and draw on it to make an image
// data can be a array of strings (to draw pixel art)
// see: https://github.com/litecanvas/game-engine/blob/main/samples/pixelart/pixelart.js
// or data can be a function with drawing operations
// see: https://github.com/litecanvas/game-engine/blob/main/samples/paint/paint.js
// the options are:
// * scale?: default is 1.
// * canvas?: a OffscreenCanvas (by default a new one).
paint(width, height, data: string[]|function, options?): ImageBitmap
/**
* ADVANCED DRAWING FUNCTIONS
*/
// get the current canvas context 2D or set a newly
ctx(context?: CanvasRenderingContext2D): CanvasRenderingContext2D
// save the canvas state
push(): void
// restore the canvas state to the last saved state
pop(): void
// Adds a translation transformation to the current matrix
translate(x: number, y: number): void
// Adds a scaling transformation to the canvas units
// horizontally (x) and/or vertically (y)
scale(x: number, y?: number): void
// Adds a rotation to the transformation matrix
rotate(radians: number): void
// Sets the alpha (opacity) value to apply when drawing new shapes and images
// see: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha
alpha(value: number): void
// Fills the current path
// see: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fill
fill(color: number): void
// Outlines the current path
// see: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/stroke
stroke(color: number): void
// Create a clipping region based in a path (in the callback)
// see: https://github.com/litecanvas/game-engine/blob/main/samples/clip/clip.js
// note: before call `clip()` you must save the context using `push()` and `pop()`
clip(callback: (ctx: CanvasRenderingContext2D) => void)
Functions for Sound
// Plays ZzFX sound effects and returns the played sound array or `false`.
// example: sfx([2,.05,598,.07,0,.19,0,1.32,9.9,-70,0,0,0,0,0,0,.3,.02,0,.04])
// see: https://killedbyapixel.github.io/ZzFX/
// note: if the first argument is omitted, a default sound is played (see DEFAULT_SFX)
// example: sfx() or sfx(null)
sfx(ZzFXparams?: number[], pitchSlide = 0, volumeFactor = 1): number[] | boolean
// Sets the ZzFX global volume factor.
// note: use 0 (zero) to mute all ZzFX sounds.
volume(value: number): void
Functions for Keyboard
// Checks if any or which key is currently pressed in your keyboard.
// example: iskeydown('space') // returns true if space bar is down
// example: iskeydown() // returns true for any key
iskeydown(key: string): boolean
// Checks if any or which key just got pressed in your keyboard.
// example: iskeypressed('space') // returns true if space bar was pressed
// example: iskeypressed() // returns true for any key
iskeypressed(key: string): boolean
Functions for Math
/** General Math */
// Calculates a linear (interpolation) value over `t`.
// example: lerp(0, 50, 0.5) returns 25
// learn more: https://gamedev.net/tutorials/programming/general-and-gameplay-programming/a-brief-introduction-to-lerp-r4954/
lerp(a: number, b: number, t: number): number
// Convert degrees to radians
deg2rad(n: number): number
// Convert radians to degrees
rad2deg(n: number): number
// Returns the rounded value of an number to optional precision.
// example: round(PI) returns 3
// example: round(PI, 3) returns 3.142
round(value: number, precision = 0): number
// Constrains a number between `min` and `max`.
// example: clamp(50, 0, 100) return 50
// example: clamp(150, 0, 100) return 100
// example: clamp(-10, 0, 100) return 0
clamp(value: number, min: number, max: number): number
// Wraps a number between `min` (inclusive) and `max` (exclusive).
// example: wrap(50,0,100) return 50
// example: wrap(125, 0, 100) return 25
wrap(value, min, max): number
// Re-maps a number from one range to another.
// example: map(2, 0, 10, 0, 100) returns 20
map(val, start1, stop1, start2, stop2, withinBounds = false ): number
// Maps a number from one range to a value between 0 and 1.
// example: norm(50, 0, 100) returns 0.5
norm(value, min, max): number
// Interpolate between 2 values using a periodic function (by default is Math.sin).
// example: wave(-100, 100, T)
wave(from: number, to: number, t: number, fn = Math.sin): number
// Returns the sine of a number in radians.
sin(angle: number): number
// Returns the cosine of a number in radians.
cos(angle: number): number
// Returns the tangent of a number in radians.
tan(angle: number): number
// Returns the angle between the positive x-axis
// and the origin (0, 0) to the point (x, y).
atan2(y:number, x: number): number
// Returns the square root of the sum of squares of its arguments.
hypot(...ns: number): number
// Returns the absolute value of a number.
abs(n: number): number
// Rounds up and returns the smallest integer greater than or
// equal to a given number.
ceil(n: number): number
// Returns the value of a number rounded to the nearest integer.
round(n: number): number
// Rounds down and returns the largest integer less than or
// equal to a given number.
floor(n: number): number
// Returns the integer part of a number
// by removing any fractional digits.
trunc(n: number): number
// Returns the smallest of the numbers given as
// input parameters, or `Infinity` if there are no parameters.
// example: min(-10, 15, -1) returns -10
min(...ns: number): number
// Returns the largest of the numbers given as input parameters,
// or `-Infinity` if there are no parameters.
// example: max(-10, 15, -1) returns 15
max(...ns: number): number
// Returns the value of a base raised to a power.
// example: pow(2, 3) returns 2³ or 8
pow(x: number, y: number): number
// Returns E (Euler's number) raised to the power of a number.
// example: exp(1) returns 2.7182... (approximately)
exp(n: number): number
// Returns the square root of a number.
sqrt(n: number): number
// Returns 1 or -1, indicating the sign of a number.
// If the number is 0, it will returns 0.
sign(n: number): number
/** Random Number Generator (RNG) */
// Generates a pseudo-random float between min (inclusive)
// and max (exclusive)
rand(min = 0, max = 1.0): number
// Generates a pseudo-random integer between min (inclusive)
// and max (inclusive)
randi(min = 0, max = 1): number
// initializes the random number generator (RNG) with an explicit seed value
// By default, the initial seed is the current timestamp (from `Date.now()`).
// Note: The value should be a integer number greater than or equal to zero.
rseed(value: number): void
Engine API
The following functions are most used internally, but also very useful when creating plugins.
// gets the canvas
canvas(): HTMLCanvasElement
// Loads a plugin.
// see: https://github.com/litecanvas/game-engine/blob/main/samples/plugin-basics/plugin-basics.js
use(callback): void
// Registers a game event callback and
// returns a function that unregister this callback.
listen(event: string, callback: Function): Function
// Triggers a game event and call its registered callbacks.
emit(event: string, arg1?, arg2?, arg3?, arg4?): void
// Sets the scale of the game's delta time (dt).
// By default is equal to 1.
// Values higher than 1 increase the speed of time,
// while values smaller than 1 decrease it.
// A value of 0 freezes time (equivalent to pausing).
timescale(value: number): void
// Sets the target FPS (frames per second)
framerate(value: number): void
// the following functions are most used by plugins...
// Defines or updates an instance property or method
def(name: string, value: any): void
// Update or reset the palette color
// example: pal(['#000', '#FFF']) is a 1-bit color palette
// example: pal() resets the default color palette
pal(colors: string[]): void
// pauses the engine loop (update & draw)
pause(): void
// resumes the engine loop
resume(): void
// returns `true` if the engine loop is paused
paused(): boolean
// shutdown the engine
// also emits the "quit" event
quit(): void
// use `stat() to get internal informations about an litecanvas' instance
// stat(0) the settings passed to that instance
// stat(1) returns true if the "init" event has already been emitted
// stat(2) the current delta time (dt)
// stat(3) the current canvas element scale (not the context 2D scale)
// stat(4) the attached event callbacks
// stat(5) the current color palette
// stat(6) the default sound used by `sfx()`
// stat(7) the current time scale
// stat(8) the current volume used by ZzFX
// stat(9) the current RNG state
// stat(10) the current font size
// stat(11) the current font family
// any other values probably will return undefined
stat(n: number): any
Playground Features
Extra packages
The following packages are automatically loaded into the playground:
- https://github.com/litecanvas/plugin-asset-loader
-
https://github.com/litecanvas/plugin-frame-rate-meter
Tip: CallFPS_METER.display(false)
in your functioninit()
to disable it. -
https://github.com/litecanvas/plugin-pixel-font
Tip: Calltextfont(PIXEL_FONT_BASIC)
ortextfont(PIXEL_FONT_MINI)
to use pixel fonts. - https://github.com/litecanvas/plugin-migrate
- https://github.com/litecanvas/utils
Public assets
We have a few assets you can use to help prototype ideas.
Cool 1-bit sprites made by Kenneylet sprites;
litecanvas({
pixelart: true
})
function init() {
// first, load the spritesheet image
loadImage('/images/sprites.png', (res, { splitFrames }) => {
// after loaded, split the image in multiple 16x16 sprites
sprites = splitFrames(res, 16, 16)
})
}
function draw() {
cls(0)
if (LOADING) return; // wait the asset loader
push()
// These sprites are 16x16 (pretty small),
// so let's zoom in 3x
scale(3)
// draw each sprite
for (let y = 0, index = 0; y < 8; y++) {
for (let x = 0; x < 8; x++, index++) {
// each index is a sprite
image(x * 16, y * 16, sprites[index])
}
}
pop()
}
Useful tools
- litepixel: Tiny pixel art editor for litecanvas games.
- ZzFX Designer: UI to generate ZzFX sounds.