This library for nodejs allows you, thanks to SDL2, to create windows and draw on the screen.
You can install this library using npm i simply2d. Node.js 22.22.2+, 24.15.0+, or 26+ is required.
This library require SDL2 in order to run. Simple DirectMedia Layer is a cross-platform library designed to provide low level access to different resources such as video. SDL2 is available for windows, linux and macos as well.
Visual Studio VC tools are required. For more, see https://github.com/nodejs/node-gyp#readme
To use Simply2D you must have installed make, a C++17 compiler, Python 3, pkg-config and the SDL2 development packages. To install SDL2 you can use the following command:
- For Ubuntu:
sudo apt install build-essential python3 pkg-config libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev - For Red Hat and Fedora:
sudo dnf install gcc-c++ make python3 pkgconf-pkg-config SDL2-devel SDL2_image-devel SDL2_ttf-devel - For Arch Linux:
sudo pacman -S --needed base-devel python pkgconf sdl2 sdl2_image sdl2_ttf
If you encounter any problems, it is recommended to install the latest version of python3 and run
python3 -m pip install setuptoolsor justpip install setuptools
On Windows you must create the following files in your project directory:
📁 bin
│ 📁 sdl
│ │ 📁 winx64
│ │ │ 📄 SDl2.dll
│ │ │ 📄 SDL2.lib
│ │ │ 📄 SDL2main.lib
│ │ │ 📄 SDL2test.lib
│ 📁 sdlimg
│ │ 📁 winx64
│ │ │ 📄 SDL2_image.dll
│ │ │ 📄 SDL2_image.lib
│ 📁 sdlttf
│ │ 📁 winx64
│ │ │ 📄 SDL2_ttf.dll
│ │ │ 📄 SDL2_ttf.lib
These files can be extracted from the following links:
- https://github.com/libsdl-org/SDL/releases/download/release-2.30.7/SDL2-devel-2.30.7-VC.zip
- https://github.com/libsdl-org/SDL_image/releases/download/release-2.8.2/SDL2_image-devel-2.8.2-VC.zip
- https://github.com/libsdl-org/SDL_ttf/releases/download/release-2.22.0/SDL2_ttf-devel-2.22.0-VC.zip
Under the lib/x64 path
To build from source, run npm install, then npm run build. Run the small framebuffer smoke test with npm test (Linux uses offscreen video). Before packing a release, supply the Windows DLLs and import libraries above in bin/; these are included in the npm package. The Windows CI job downloads them before building.
The Canvas class allows you to create a canvas and to draw on it
import { Canvas } from "simply2d";
const canvas = new Canvas(
"my canvas", // window title
600, // window width
400, // window height
);You can specify other window options
const canvas = new Canvas("title", 200, 400, 0, 0, {
mode: "fullscreen",
resizable: false,
scale: 2,
antiAliasing: true
})show(): voidShow the window
hide(): voidHide the window
setBackgroundColor(color: RGBAColor): voidSet the background color. An RGBAColor is an object that contains red, green, blue and alpha properties.
sleep(ms: number): voidSleep ms milliseconds
drawPoint(color: RGBAColor, position: Position): voidDraw a point on the screen. Position is an object with the x and y properties.
drawLine(color: RGBAColor, from: Position, to: Position): voidDraw a line from from coordinates to to coordinates
drawRectangle(color: RGBAColor, pos: Position, width: number, height: number, fill?: boolean): voidDraw a rectangle in the canvas
get width(): numberReturn the window width
get height(): numberReturn the window height
clear(): voidClear the screen
loadRawData(pixels: Uint8Array, bitPerPixel: 8 | 16 | 24 | 32): voidWrite directly into the video buffer
loadPNG(filename: string): voidWrite an PNG image into the canvas
loadJPG(filename: string): voidWrite a JPG image into the canvas
dumpPNG(filename: string): voidSave the canvas as a PNG file
dumpJPG(filename: string): voidSave the canvas as a JPG file
getScale(): numberReturn the scale factor
onClick(callback: (x: number, y: number) => void): voidOn click event
onKeyDown(callback: (key: Key) => void): voidOn key down event
onKeyUp(callback: (key: Key) => void): voidOn key up event
initRenderSequence(): voidIt is used to initialize the rendering sequence. Every drawing process will not be displayed until exposeRender is called
exposeRender(): voidShows rendering
waitFrame(): voidSleep for a certain time before the next frame is rendered
loop(callback: () => void): voidStart the rendering loop
onKeysDown(callback: (key: Key[]) => void): voidOn keys down event
onKeysUp(callback: (key: Key[]) => void): voidOn keys up event
loadFont(fontName: string, filePath: string): voidLoad a new font
drawText(text: string, fontName: string, size: number, color: RGBAColor, start: Position): voidDraw text on the canvas
drawArc(color: RGBAColor, center: Position, radius: number, startingAngle: number, endingAngle: number): voidDraw an arc
static convertPolarCoords(center: Position, angle: number, radius: number): PositionConvert polar coordinates into x, y coordinates
loadTexture(textureID: string, filePath: string): voidLoad a new texture from the specified file
drawTexture(textureID: string, pos: Position): voidDraw a previously loaded texture
static getScreenResolution(): ResolutionGet the screen resolution
getTextureResolution(textureID: string): ResolutionGet the resolution of a previously loaded texture
drawPath(path: Path, pos?: Position, color?: RGBAColor)Draw a path
addLayer(layerId: string): voidAdd a new layer
removeLayer(layerId: string): voidRemove layer
changeLayer(layerId: string): voidChange current layer
useMainLayer(): voidChange to the main default layer
get frameTime(): numberGet current frame time, only if the scene is rendered with loop
get fps(): numberGet current frame time, only if the scene is rendered with loop
getLayers(): Layer[]Get layers in order of appearance
activateLayer(layerID: string): voidActivate a layer
deactivateLayer(layerID: string): voidDeactivate a layer
get antialiasing(): booleanGet antialiasing flag
set antialiasing(): voidSet antialiasing flag
clearAll(): voidClear all layers, including the main layer
moveLayer(layerID: string, direction: "up" | "down", steps: number = 1): voidChange layer rendering priority
attach(buffer: Uint8Array, bitPerPixel: PixelFormat): voidAttach a buffer to the video memory. The loop and every other drawing functions will be disabled.
detach(): voidDetach the current buffer from the video memory
close(): voidClose the window
endLoop(): voidTerminate the current loop
get mousePosition(): PositionReturn the current mouse position
applyFilter(fn: (value: number, index: number, buffer: Uint8Array) => number): voidApply a callback to every byte of the current rendering target and display the result. The callback receives the byte value, byte index, and buffer. Updates happen in place, in index order; returned values are converted to unsigned bytes. This stops the render loop, like attach. Detach any existing buffer first. The temporary buffer is always detached, including when the callback throws.
canvas.applyFilter(value => Math.floor(value / 2));type CanvasOptions = {
mode?: "fullscreen" | "minimized" | "maximized" | "hidden" | "shown",
resizable?: boolean,
scale?: number,
antiAliasing?: boolean,
removeWindowDecoration?: boolean
}It is possible to access constant positions relative to the size of the canvas. Example:
import { Canvas, Colors } from "simply2d"
const canvas = new Canvas("myCanvas", 200, 200);
canvas.drawLine(Colors.BLUE, canvas.TOP_LEFT /* the top left corner */, canvas.BOTTOM_RIGHT /* the bottom right corner */);Colors is an object that contains different standard colors and some useful function
import { Canvas, Colors } from "simply2d";
const canvas = new Canvas("title", 100, 100);
canvas.setBackgroundColor(Colors.RED); // #FF0000 hex color
canvas.drawLine(
Colors.BLACK, // #000000 hex color
{
x: 0,
y: 0
},
{
x: canvas.getWidth(),
y: canvas.getHeight()
}
);from8bit(color256: number): RGBAColorConvert an 8 bit color into a 24 bit color
from16bit(color: number): RGBAColorConvert a 16 bit color into a 24 bit color
from24bit(color: number): RGBAColorConvert a 24 bit color number into a 24 bit color RGBAColor object
from32bit(color: number): RGBAColorConvert a 32 bit color number into a RGBAColor object
Is a type for storing coordinates
import { Position } from "simply2d" // only in typescript
let cord: Position = {
x: 203,
y: 301
}Used to save RGBA color values
import { RGBAColor } from "simply2d" // only in typescript
let color: RGBAColor = {
red: 255,
green: 255,
blue: 0,
alpha: 255
}Used to save a pair of width and height values
import { Resolution } from "simply2d"
let res: Resolution = {
w: 1920,
h: 1080
}A path is an object used to represent a polyline
import { Path } from "simply2d";
const p = new Path();
p.setStart({ x: 10, y: 15 });
p.pushLine({ x: 20, y: 60 });
p.close();Static class that stores all the available pixel formats
PixelFormats.rgb332;
PixelFormats.rgb565;
PixelFormats.rgb888;
PixelFormats.rgba8888;