Live demo

Canvas VS WebGL


[GREE Tech Talk #08] You Don't Know WebGL

[Chrome Tech Talk Night #8] Beating Canvas 2D in Its Own Territory: WebGL+Tesspathy


Tesspathy is a Javascript utility library for converting vector representation (aka path) of 2d graphics into the form (basically triangles) capable of being fed to GL-like (e.g. WebGL) APIs.



Install using npm

npm install tesspathy

Then require it into any module

var Tesspathy = require('tesspathy');
var tLoactions = [/* ... */], tLabels = [/* ... */];
var tResult = Tesspathy.triangulate(tLocations, tLabels);

To use Tesspathy from a browser, download the appropriate file(s) from the following:

And then add it as a script tag to your page

<script src="tesspathy.min.js"></script>
  var tLoactions = [/* ... */], tLabels = [/* ... */];
  var tResult = Tesspathy.triangulate(tLocations, tLabels);


Live demo


Input data of shape contours with one or multiple separated regions, zero or multiple holes, can be all passed in together, without explicit separation. The same for lines with one or multiple connected/disconnected strokes.

Tesspathy.triangulate(locations, labels)

Tessellate one or multiple closed shapes (with zero or multiple holes possibly) defined by locations and labels.

Tesspathy.triangulateLine(locations, labels, lineStyle)

Tessellate one or multiple strokes defined by locations, labels, and lineStyle.


Set the values to be used when generating the fillCoordinates field of the output object of both Tesspathy.triangulate and Tesspathy.triangulateLine. The meaning and usage of this fillCoordinates is not defined in the scope of Tesspathy project. One possible usage is to pass it as another vertex attribute to shader program for certain rendering effects, such as resolution independent curve (live demo).


Get the current values used to generate the fillCoordinates field of the output object.



Array of point locations, of the following form:

  [x0, y0], [x1, y1], [x2, y2], ... , [xN, yN],    // 1st shape or line
  [xN+1, yN+1], [xN+2, yN+2], ... , [xN+M, yN+M],  // 2nd shape or line
  ...   // more shapes or lines


Array of point labels to indicating 1. the start of a new shape or line, 2. normal point or control point(of Bezier curve).

For example:

// START = [Tesspathy.PATH_START], ANCHOR = [Tesspathy.PATH_ANCHOR], CONTROL = [Tesspathy.PATH_CONTROL];

  START, ANCHOR, CONTROL, ..., ANCHOR,   // 1st shape or line
  START, CONTROL, ANCHOR, ..., ANCHOR,   // 2nd shape or line
  ...   // more shapes or lines


Object defining the line style used to render strokes, of the following form:

  width: 20,
  cap: 'round',
  join: 'round'


Object defining the values to be used when generating the fillCoordinates field of the output. For example:

  straight: {s: STRAIGHT_S, t: STRAIGHT_T},
  out_anchor0: {s: OUT_ANCHOR0_S, t: OUT_ANCHOR0_T},
  out_control: {s: OUT_CONTROL_S, t: OUT_CONTROL_T},
  out_anchor1: {s: OUT_ANCHOR1_S, t: OUT_ANCHOR1_T},
  in_anchor0: {s: IN_ANCHOR0_S, t: IN_ANCHOR0_T},
  in_control: {s: IN_CONTROL_S, t: IN_CONTROL_T},
  in_anchor1: {s: IN_ANCHOR1_S, t: IN_ANCHOR1_T}


The output of both Tesspathy.triangulate and Tesspathy.triangulateLine will be an Object of the following form:

  triangleLocations: [x0, y0, x1, y1, ..., xK, yK]
  fillCoordinates: [s0, t0, s1, t1, ..., sK, yK]
  triangleIndices: [0, 1, 2, 1, 3, 4, ..., K-5, K-3, K-2]

This output can be used directly by WebGL. For example:

var tPosition = gl.getAttribLocation(...);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(result.triangleLocations), gl.STATIC_DRAW);
gl.vertexAttribPointer(tPosition, 2, gl.FLOAT, false, 0, 0);

var tCoord = gl.getAttribLocation(...);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(result.fillCoordinates), gl.STATIC_DRAW);
gl.vertexAttribPointer(tCoord, 2, gl.FLOAT, false, 0, 0);

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(result.triangleIndices), gl.STATIC_DRAW); 

gl.drawElements(gl.TRIANGLES, result.triangleIndices.length, gl.UNSIGNED_SHORT, 0);

Thus, if you set your GL status and matrix uniform(s) correctly, and write your shaders (especially fragment shader) well, you will see your shapes or lines defined in vector form being rendered by using WebGL. If there is any problem, please first have a look at the live demo provided.



Guangyao Liu


We use GitHub issues to track requests and public bugs. Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue.


Copyright © 2015 Guangyao Liu / GREE, Inc.

Licensed under the MIT License.