Skip to content

Rendering API

Olivier Biot edited this page Apr 5, 2026 · 9 revisions

The melonJS rendering API is designed to feel familiar to anyone who has used the HTML5 Canvas 2D API (CanvasRenderingContext2D). Whether you choose the Canvas or WebGL renderer, the API remains the same — write your game once, and it runs on both backends with zero code changes.

Quick Example

// This code works identically on Canvas and WebGL
renderer.save();
renderer.translate(100, 50);
renderer.rotate(Math.PI / 4);
renderer.setColor("#FF0000");
renderer.fillRect(0, 0, 64, 64);
renderer.restore();

If you've used ctx.save(), ctx.translate(), ctx.fillRect() on a Canvas 2D context, you already know the melonJS rendering API.

Live Examples

See these features in action:

  • Graphics — shapes, paths, bezier curves, dashed lines, masks, transforms
  • Gradients — linear/radial gradients on rects, ellipses, polygons, rounded rects
  • Blend Modes — all supported composite operations

API Reference Table

The table below maps every melonJS renderer method to its Canvas 2D equivalent.

State Management

melonJS Canvas 2D Equivalent Description
save() ctx.save() Push the current renderer state onto a stack
restore() ctx.restore() Pop and restore the most recently saved state
reset() Reset the entire renderer context to its default state
clear() Prepare the framebuffer for a new frame
flush() Flush the render pipeline (WebGL batches; no-op on Canvas)

Transforms

melonJS Canvas 2D Equivalent Description
translate(x, y) ctx.translate(x, y) Add a translation transformation
rotate(angle) ctx.rotate(angle) Add a rotation (radians) to the transformation matrix
scale(x, y) ctx.scale(x, y) Add a scaling transformation
transform(a, b, c, d, e, f) ctx.transform(a, b, c, d, e, f) Multiply the current matrix by the given one
setTransform(a, b, c, d, e, f) ctx.setTransform(a, b, c, d, e, f) Reset the matrix then apply the given one
resetTransform() ctx.setTransform(1,0,0,1,0,0) Reset the transformation matrix to identity
setProjection(matrix) Set the projection matrix (orthographic)

Color, Gradients & Alpha

melonJS Canvas 2D Equivalent Description
setColor(color) ctx.fillStyle / ctx.strokeStyle Set the current fill and stroke color (accepts Color, string, or Gradient)
getColor() Get the current fill and stroke color
createLinearGradient(x0, y0, x1, y1) ctx.createLinearGradient(x0, y0, x1, y1) Create a linear gradient fill
createRadialGradient(x0, y0, r0, x1, y1, r1) ctx.createRadialGradient(x0, y0, r0, x1, y1, r1) Create a radial gradient fill
gradient.addColorStop(offset, color) gradient.addColorStop(offset, color) Add a color stop to a gradient
setGlobalAlpha(alpha) ctx.globalAlpha = alpha Set the global alpha (opacity)
getGlobalAlpha() ctx.globalAlpha Get the current global alpha
setTint(tint, alpha) Set a coloring tint for sprite rendering
clearTint() Clear the current rendering tint
setBlendMode(mode) ctx.globalCompositeOperation Set the blend/composite mode
getBlendMode() ctx.globalCompositeOperation Get the current blend mode

Gradient example:

const gradient = renderer.createLinearGradient(0, 0, 200, 0);
gradient.addColorStop(0, "#00FF00");
gradient.addColorStop(0.5, "#FFFF00");
gradient.addColorStop(1, "#FF0000");
renderer.setColor(gradient);
renderer.fillRect(10, 10, 200, 24);

Drawing — Rectangles

melonJS Canvas 2D Equivalent Description
fillRect(x, y, w, h) ctx.fillRect(x, y, w, h) Fill a rectangle
strokeRect(x, y, w, h) ctx.strokeRect(x, y, w, h) Stroke a rectangle outline
clearRect(x, y, w, h) ctx.clearRect(x, y, w, h) Erase pixels in a rectangular area
clearColor(color, opaque) Clear the framebuffer with a solid color
fillRoundRect(x, y, w, h, r) ctx.roundRect() + ctx.fill() Fill a rounded rectangle
strokeRoundRect(x, y, w, h, r) ctx.roundRect() + ctx.stroke() Stroke a rounded rectangle outline

Drawing — Paths

melonJS Canvas 2D Equivalent Description
beginPath() ctx.beginPath() Start a new path
closePath() ctx.closePath() Close the current sub-path
moveTo(x, y) ctx.moveTo(x, y) Move to a point without drawing
lineTo(x, y) ctx.lineTo(x, y) Draw a straight line to a point
quadraticCurveTo(cpx, cpy, x, y) ctx.quadraticCurveTo(cpx, cpy, x, y) Add a quadratic Bezier curve to the path
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) Add a cubic Bezier curve to the path
arcTo(x1, y1, x2, y2, radius) ctx.arcTo(x1, y1, x2, y2, radius) Add a circular arc using control points and radius
rect(x, y, w, h) ctx.rect(x, y, w, h) Add a rectangle to the current path
roundRect(x, y, w, h, radii) ctx.roundRect(x, y, w, h, radii) Add a rounded rectangle to the current path
stroke(shape) ctx.stroke() Stroke the current path or a given shape
fill(shape) ctx.fill() Fill the current path or a given shape

Bezier curve example:

renderer.beginPath();
renderer.setColor("#10b981");
renderer.moveTo(0, 100);
renderer.bezierCurveTo(100, 0, 200, 200, 300, 100);
renderer.stroke();

Drawing — Shapes

melonJS Canvas 2D Equivalent Description
strokeArc(x, y, r, start, end) ctx.arc() + ctx.stroke() Stroke an arc
fillArc(x, y, r, start, end) ctx.arc() + ctx.fill() Fill an arc
strokeEllipse(x, y, w, h) ctx.ellipse() + ctx.stroke() Stroke an ellipse
fillEllipse(x, y, w, h) ctx.ellipse() + ctx.fill() Fill an ellipse
strokeLine(x1, y1, x2, y2) ctx.moveTo() + ctx.lineTo() + ctx.stroke() Stroke a line between two points
fillLine(x1, y1, x2, y2) ctx.moveTo() + ctx.lineTo() + ctx.fill() Fill a line between two points
strokePolygon(poly) ctx.lineTo() loop + ctx.stroke() Stroke a polygon
fillPolygon(poly) ctx.lineTo() loop + ctx.fill() Fill a polygon
strokePoint(x, y) Stroke a single point
fillPoint(x, y) Fill a single point

Images & Patterns

melonJS Canvas 2D Equivalent Description
drawImage(image, ...) ctx.drawImage(image, ...) Draw an image (supports all 3/5/9 argument forms)
createPattern(image, repeat) ctx.createPattern(image, repeat) Create a repeating image pattern
drawPattern(pattern, x, y, w, h) ctx.fillStyle = pattern + ctx.fillRect() Draw a pattern within a rectangle

Clipping & Masking

melonJS Canvas 2D Equivalent Description
clipRect(x, y, w, h) ctx.rect() + ctx.clip() Clip rendering to a rectangular region
setMask(mask, invert) ctx.clip() / gl.stencilFunc() Apply an arbitrary shape as a rendering mask
clearMask() Remove the current rendering mask

Line Style

melonJS Canvas 2D Equivalent Description
setLineDash(segments) ctx.setLineDash(segments) Set the dash pattern for stroke operations
getLineDash() ctx.getLineDash() Get the current dash pattern
lineWidth ctx.lineWidth Line thickness (property, not a method)

Dashed line example:

renderer.setLineDash([10, 5]);
renderer.strokeLine(0, 50, 300, 50);
renderer.setLineDash([]); // back to solid

Pixel Smoothing

melonJS Canvas 2D Equivalent Description
setAntiAlias(enable) ctx.imageSmoothingEnabled Enable or disable image smoothing/anti-aliasing

Canvas Access

melonJS Canvas 2D Equivalent Description
getCanvas() canvas Return the underlying canvas element
getContext() canvas.getContext('2d') Return the underlying rendering context
resize(w, h) Setting canvas.width / canvas.height Resize the rendering canvas
overlaps(bounds) Check if a bounding box overlaps the visible area
toBlob(type, quality) canvas.toBlob() Export the current frame as a Blob
toDataURL(type, quality) canvas.toDataURL() Export the current frame as a data URL
toImageBitmap(type, quality) createImageBitmap(canvas) Export the current frame as an ImageBitmap

WebGL-Specific

These methods are available on both renderers but only return meaningful results on WebGL. On Canvas they are safe to call but have no effect or return empty/default values:

melonJS Description
addBatcher(batcher, name) Add a custom batcher for specialized rendering (WebGL only)
setBatcher(name, shader) Switch the active rendering batcher (WebGL only)
setViewport(x, y, w, h) Set the WebGL viewport rectangle (WebGL only)
WebGLVersion Returns the WebGL version in use (1 or 2), undefined on Canvas
getSupportedCompressedTextureFormats() List supported GPU compressed texture formats (returns empty on Canvas)

Key Differences from Canvas 2D

While the API mirrors Canvas 2D closely, there are a few design differences:

  1. Unified color setter — melonJS uses setColor(color) to set both fillStyle and strokeStyle at once, rather than having two separate properties.

  2. Convenience shape methods — Instead of building paths manually, melonJS provides direct strokeRect, fillEllipse, strokePolygon, etc. methods that accept melonJS shape objects (Rect, Ellipse, Polygon).

  3. TintingsetTint() / clearTint() provide sprite-level color tinting with no Canvas 2D equivalent.

  4. Automatic batching — The WebGL renderer automatically batches draw calls. Call flush() explicitly only when you need to force a batch submission (e.g. before reading pixels).

  5. Blend modes — Both renderers support the same blend mode names (normal, multiply, screen, additive, etc.), abstracting away the difference between globalCompositeOperation (Canvas) and GL blend functions (WebGL).

Choosing a Renderer

import { Application, video } from "melonjs";

// Auto-detect (WebGL with Canvas fallback)
const app = new Application(800, 600, { renderer: video.AUTO });

// Force Canvas
const app = new Application(800, 600, { renderer: video.CANVAS });

// Force WebGL
const app = new Application(800, 600, { renderer: video.WEBGL });

The renderer is accessed via app.renderer and provides the full API listed above regardless of which backend is active.

Path2D

melonJS uses an internal Path2D class to build and tessellate 2D paths for the WebGL renderer. On Canvas, path methods (moveTo, lineTo, bezierCurveTo, etc.) are direct pass-throughs to the native context. On WebGL, they are routed through Path2D which tessellates curves into line segments for the primitive batcher.

Path2D also supports SVG path strings for defining shapes:

import Path2D from "melonjs";

// a heart shape using arcs and quadratic curves
const heart = new Path2D(
    "M 10 30 A 20 20 0 0 1 50 30 A 20 20 0 0 1 90 30 Q 90 60 50 90 Q 10 60 10 30 Z"
);

Supported SVG commands: M (moveTo), L (lineTo), H (horizontal line), V (vertical line), Q (quadratic Bezier), C (cubic Bezier), A (arc), Z (close path).

Custom Drawing in a Renderable

To draw custom graphics, override the draw method of a Renderable:

import { Renderable } from "melonjs";

class MyGraphics extends Renderable {
    constructor() {
        super(0, 0, 200, 200);
        this.anchorPoint.set(0, 0);
    }

    draw(renderer) {
        // sky gradient
        const sky = renderer.createLinearGradient(0, 0, 0, 100);
        sky.addColorStop(0, "#1a1a6e");
        sky.addColorStop(1, "#FF6B35");
        renderer.setColor(sky);
        renderer.fillRect(0, 0, 200, 100);

        // dashed horizon line
        renderer.setLineDash([8, 4]);
        renderer.setColor("#FFFFFF");
        renderer.strokeLine(0, 100, 200, 100);
        renderer.setLineDash([]);

        // bezier curve hill
        renderer.beginPath();
        renderer.setColor("#2d5016");
        renderer.moveTo(0, 150);
        renderer.bezierCurveTo(50, 80, 150, 80, 200, 150);
        renderer.lineTo(200, 200);
        renderer.lineTo(0, 200);
        renderer.fill();
    }
}

Clone this wiki locally