TWO.js 1.0 Documentation
Download TWO.js here!
TWO.js is a small 2D graphics library I made mainly for my own use. Alongside the viewport coordinate system used by default by the Canvas API, TWO.js adds a world coordinate system that is independent of the size and location of the viewport. Functions are provided for rotating, zooming, and moving the camera around this coordinate system. Both coordinate systems can be used simultaneously.
0. Initialization
Create a canvas as usual, then use TWO.getEnhancedContext() to get a CanvasRenderingContext2D object, enhanced with TWO.js functions.
// create a canvas element
let c = document.createElement("canvas");
// get 2D context enhanced with TWO.js functions
let ctx = TWO.getEnhancedContext(c);
// add canvas to document
document.body.appendChild(c);
By default, zooming and panning with the mouse is disabled. They can be individually enabled by passing an object with zooming and/or panning as the second argument:
// zooming and panning allowed
let ctx = TWO.getEnhancedContext(c, {zooming:true, panning:true});
NOTE: Zooming and panning require an animation loop to work.
Optionally, you can TWO.maximize() the canvas. This will make the canvas fill the entire viewport, even after resizing the window.
// make the canvas fill the viewport
TWO.maximize(c);
1. The Camera
The position of the camera is defined as the world coordinates at the center of the canvas. The camera is positioned at the origin (0, 0) by default. Like the regular canvas viewport coordinates, a positive Y coordinate means down.
The zoom level is defined as the ratio between the size of an object in world coordinates, and its size in the viewport measured in pixels. When the zoom level is 3, a 20 x 10 rectangle will be 60 x 30 pixels large.
The rotation of the camera is defined as a counterclockwise rotation in radians. The camera position does not change while rotating, so the camera will rotate around its center.
NOTE: The camera itself rotates, not the objects. If the camera rotates counterclockwise, the objects it sees will appear to rotate clockwise.
2. Functions
2.1. World coordinate versions of existing methods
To draw something using world coordinates, call an existing method of CanvasRenderingContext2D, but add an underscore at the beginning of the name. The following methods are supported:
-
Rectangles
- ctx._clearRect()
- ctx._fillRect()
- ctx._strokeRect()
- ctx._fillText()
- ctx._strokeText()
- ctx._moveTo()
- ctx._lineTo()
- ctx._bezierCurveTo()
- ctx._quadraticCurveTo()
- ctx._arc()
- ctx._arcTo()
- ctx._ellipse()
- ctx._rect()
- ctx._roundRect()
- ctx._stroke()
- ctx._drawImage()
- ctx._rotate()
- ctx._scale()
- ctx._translate()
- ctx._transform()
- ctx._getTransform()
- ctx._setTransform()
- ctx._resetTransform()
Text
Paths
Images
Transformations
2.2. Camera control
2.2.1. ctx.setCameraPosition(x, y)
Sets the camera position to the point (x, y)
2.2.2. ctx.getCameraPosition()
Returns the camera position in an object with two properties, x and y.
2.2.3. ctx.setCameraX(x)
Sets the camera's x coordinate. The y coordinate is left unchanged.
2.2.4. ctx.setCameraY(y)
Sets the camera's y coordinate. The x coordinate is left unchanged.
2.2.5. ctx.translateCamera(x, y)
Translates the camera position by (x, y) in viewport coordinates.
2.2.6. ctx._translateCamera(x, y)
Translates the camera position by (x, y) in world coordinates.
2.2.7. ctx.zoom(n)
Multiplies the current zoom level by n.
2.2.8. ctx.setZoom(n)
Sets the zoom level to n.
2.2.9. ctx.getZoom()
Returns the current zoom level.
2.2.10. ctx.rotateCamera(n)
Rotates the camera counterclockwise by n radians.
2.2.11. ctx.setCameraRotation(n)
Sets the camera rotation to n radians.
2.2.12. ctx.getCameraRotation()
Returns the current camera rotation in radians.
2.3. Coordinate conversion
2.3.1. ctx.v2w(x, y)
Converts viewport coordinates to world coordinates; returns the world coordinates currently located at viewport coordinates (x, y). Returns an object with two properties, x and y.
2.3.2. ctx.w2v(x, y)
Converts world coordinates to viewport coordinates; returns the viewport coordinates currently located at world coordinates (x, y). Returns an object with two properties, x and y.
3. Examples
3.1. Drawing in both coordinate systems
Both coordinate systems can be used simultaneously:
// viewport coordinates
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 30, 30);
// world coordinates
ctx.fillStyle = "dodgerblue";
ctx._fillRect(-30, -30, 60, 60);
3.2. Line width
The line width can be relative to viewport coordinates or world coordinates, depending on which version of the stroke method is called.
ctx.zoom(5);
ctx.lineWidth = 2;
// draw left circle
ctx.beginPath();
ctx._arc(-13, 0, 10, 0, 2*Math.PI);
ctx.stroke(); // 2 pixels wide (viewport coordinates)
// draw right circle
ctx.beginPath();
ctx._arc(13, 0, 10, 0, 2*Math.PI);
ctx._stroke(); // 2 units wide (world coordinates)
3.3. Lines between viewport coordinates and world coordinates
Using the example in 3.1, we can draw a line between viewport coordinates and world coordinates as follows:
// viewport coordinates
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 30, 30);
// world coordinates
ctx.fillStyle = "dodgerblue";
ctx._fillRect(-30, -30, 60, 60);
ctx.strokeStyle = "lime";
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(25, 25); // viewport coordinates
ctx._lineTo(0, 0); // world coordinates
ctx.stroke();
3.4. Transformations
The world coordinate system has its own transformation methods:
ctx._fillRect(-50, -50, 100, 100);
ctx._rotate(Math.PI/4);
ctx._scale(3, 0.5);
ctx.fillStyle = "red";
ctx._fillRect(-30, -30, 60, 60);
ctx._resetTransform();