• Stars
    star
    130
  • Rank 277,575 (Top 6 %)
  • Language
    C
  • License
    MIT License
  • Created over 5 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

๐Ÿ–ผ๏ธ Library written in C providing a friendly layer of abstraction for interacting with the HTML Canvas API when compiling with Emscripten to WebAssembly.

Build Status

wasm-canvas

wasm-canvas is a C99-compliant layer of abstraction for interacting with the HTML Canvas API.

This library is intended for use in projects compiled with Emscripten targeting WebAssembly.

Purpose

Familiarity

If you've worked with the Canvas API from JavaScript, the syntax for drawing is simple and friendly, as JavaScript tends to be.

Although JavaScript excels in readability, it often lacks in optimizability. Web applications with high-performance requirements may turn to WebAssembly compiled from C.

For applications with visual components, interacting with the Canvas API from C feels unfriendly. This library provides an interface for doing so which more closely resembles the syntax used in JavaScript.

"Object-Oriented"

The library is written in C, not an object-oriented programming language. However, the design is patterned less like idiomatic C and more like a JavaScript programmer might expect.

Some C idioms still shine through. With no garbage collector or constructors, create... and free... functions are provided to allocate, set up, and free the object-like structs. The structs are populated primarily by function pointers to make calls as similar to JavaScript as possible. Nearly all member functions require a pointer to their parent struct as the first parameter as there is no implicit this present in C.

Why not C++?

There are a lot of reasons.

Using the Library

Include the Headers

Currently, this is not a header-only library. Be sure that for each header included at compile time you introduce the corresponding source file at link time. See Hello World below for an example

For the Canvas API and drawing context functionality:

#include "canvas.h"

For access to the DOM Window object:

#include "window.h"

Creating a New Canvas

Use the createCanvas() function to insert a new canvas element into the HTML.

HTMLCanvasElement *myCanvas = createCanvas("testCanvas");

A new <canvas> element has dimensions 300Wx150H by default.

Using an Existing Canvas

If your HTML already has a canvas element you'd like to bind to...

<canvas id="someCanvas"></canvas>

... use createCanvas() with the existing element's id.

HTMLCanvasElement *myCanvas = createCanvas("someCanvas");

Drawing

Most, but not all of the functions available with the 2D rendering context in JavaScript are available.

Some functionality varies from JavaScript. Setting a field of the rendering context like font, for example, can be accomplished with a setter setFont() function. There is a corresponding getter getFont() function to read from the field.

For a full list of drawing functions available, see the CanvasRenderingContext2D Struct Reference.

Window()

#include "window.h"

The DOM Window object, accessible via the global window in JavaScript, provides some useful functionality when used in conjunction with a canvas.

For example, a canvas can be expanded in size to fill the current window.

myCanvas->setHeight(myCanvas, Window()->getInnerHeight());
myCanvas->setWidth(myCanvas, Window()->getInnerWidth());

Note that window functions do not require a pointer to the struct as the first parameter. It is assumed that there is only one window, and you are referring to that one.

Cleaning Up

Some memory is dynamically allocated for each HTMLCanvasElement created. Memory is only allocated for the HTMLWindow if it is used at least once in your program.

Any function return values that needed to be dynamically allocated will also be freed here.

Free the memory for each canvas using freeCanvas().

freeCanvas(myCanvas);

And, if you've used the Window() function at least once, free it using freeWindow().

freeWindow(Window());

Documentation

wasm-canvas

View the Doxygen

Emscripten

Installation Instructions

Emscripten API

Examples

Hello World

This is how you might draw something simple, like the text "Hello World" on a new canvas.

Although not required, I recommend giving Emscripten at least a basic HTML template to clearly see your canvas. If you choose not to provide a template, the default template does include a canvas element that you can bind to (see Using the Library above).

Directory Listing

  • build/
  • canvas.c [wasm-canvas]
  • canvas.h [wasm-canvas]
  • template.html (optional)
  • hello.c

file: template.html

<!DOCTYPE html>
<html>
    <body>
        {{{ SCRIPT }}}
    </body>
</html>

file: hello.c

#include "canvas.h"

int main(void) {
    HTMLCanvasElement *canvas = createCanvas("myCanvas");
    CanvasRenderingContext2D *ctx = canvas->getContext(canvas, "2d");
    ctx->setFont(ctx, "48px serif");
    ctx->fillText(ctx, "Hello World", 0, 150, -1);
    freeCanvas(canvas);
    return 0;
}

Compiling & Linking

emcc -Wall hello.c canvas.c -o hello.o
emcc --shell-file template.html hello.o -o build/index.html

Or, more verbosely:

emcc -Wall canvas.c -o canvas.o
emcc -Wall -I canvas.h hello.c -o hello.o
emcc --shell-file template.html hello.o canvas.o -o build/index.html

Or, less verbosely:

emcc --shell-file template.html hello.c canvas.c -o build/index.html