Wrapper for HTML Canvas Element adding helpful methods and a simplified interface
npm install utility-canvas
You can import the UtilityCanvas
class and instantiate it
import UtilityCanvas from "utility-canvas";
const myCanvas = document.getElementById("my-canvas");
// all properties are optional
const uCanvas = new UtilityCanvas({
canvas: myCanvas, // provide an existing canvas element or one will be created by default
width: 1024, // in pixels (default)
height: 1024, // in pixels (default)
parent: null // provide an element to append the canvas to (default)
})
The UtilityCanvas constructor exposes the static COMPOSITE
property, which is a list of more intuitive, human-readable operation names for use in setCompositeOperation
the canvas element attached to this instance
width of canvas in pixels
height of canvas in pixels
the CanvasRenderingContext2D fetched by running canvas.getContext('2d')
The UtilityCanvas class exposes many utility methods that wrap and extend familiar CanvasRenderingContext2D methods. These methods all return this
, which allows you to chain method calls:
const uCanvas = new UtilityCanvas({ parent: document.body });
uCanvas
.rect({ width: 100, height: 100, color: "red" })
.arc({ radius: 200, center: { x: 500, y: 500 }, color: "blue" })
.setStroke({ thickness: 10, color: "limegreen" })
.hexagon({ radius: 150, stroke: true })
UtilityCanvas allows you to set the global fillStlye, stokeStyle, composite operation, and alpha. These values, once set, will be applied to all subsequent draws. However, in any individual draw call, you have the option to set one-off overwrite values for each global property. In this case, the state of the global context settings is saved using ctx<CanvasRenderingContext2D>.save()
, the one-off values are set, and once the draw call is finished, ctx<CanvasRenderingContext2D>.restore()
restores the saved state. This global vs one-off design is meant to be convenient and intuitive, but make sure you're always aware of what your global settings are.
Dynamically resize the canvas by providing a new width and/or height, in pixels
uCanvas.resize({
width: 2048,
height: 2048
})
Sets the global fillStyle, which is applied to any draw methods that set their fill
property to true
. The default value is #000
(black)
uCanvas
.setColor("red") // sets global fillStyle to "red"
.rect({ width: 100, height: 100, fill: true }) // this rectangle will be filled "red"
Sets the global lineWidth and strokeStyle, which are applied to any draw methods that set their stroke
property to true
. The default stroke color is #000
(black) and the default thickness is 1.0
uCanvas
.setStroke({ thickness: 20, color: "red" }) // sets global fillStyle to "red"
.rect({ width: 100, height: 100, stroke: true }) // this rectangle will be outlined in thick "red"
Sets the globalCompositeOperation, which is applied to any subsequent draw calls. You can provide a string from the list of operations or use the UtilityCanvas
's static property COMPOSITE
with more self-describing, human-readable operation names. The default value is source-over
uCanvas
.setCompositeOperation(UtilityCanvas.COMPOSITE.BEHIND) // all draw calls will be drawn "behind" existing elements (equivalent to "destination-over")
Sets the globalAlpha, which is applied to any subsequent draw calls. The default value is 1.0
(opaque)
uCanvas
.setAlpha(0.5) // sets global transparency value to 50%
.rect({ width: 100, height: 100, color: "red" }) // this rectangle will be 50% transparency red
This is a mostly internal method that gets called when draw calls use one-off settings, but you can use it to set all of the above settings in one call
uCanvas
._parseSettings({
color: "red",
strokeSettings: {
thickness: 20,
color: "blue"
},
operation: UtilityCanvas.COMPOSITE.BEHIND,
alpha: 0.75
}) // sets global settings, equivalent to using each configuration method separately
.rect({ width: 100, height: 100, color: "black" }) // this rect calls _parseSettings to set its color to black
A convenience method for clearing the entire canvas to a completely blank state.
uCanvas.rect({ width: 100, height: 100, color: "red" }); // draw something to canvas
setTimeout(() => uCanvas.clear(), 2000); // wait 2s, then clear the canvas
Wraps the ctx<CanvasRenderingContext2D>.clearRect
method. Allows for clearing portions of the canvas
uCanvas.rect({ width: 100, height: 100, color: "red" }); // draw something to canvas
setTimeout(() => uCanvas.clearRect({ width: 100, height: 100 }), 2000); // wait 2s, then clear only the rect
Downloads the canvas as an image, allowing you to specify the format and filename. Default behavior is to download a jpg with the name "export.jpg"
uCanvas.download("image/png", "my-totally-sick-canvas-export.png");
Converts the current canvas into a base64 dataURL string using the ctx<CanvasRenderingContext2D>.toDataURL()
method, allowing you to specify the format (default = image/jpeg) and quality (default = 1.0)
const data = uCanvas.getDataURL("image/jpeg", 0.5);
const img = document.getElementById("screenshot-img");
img.src = data;
Accepts a base64 dataURL string and paints it to the canvas, stretching it, if necessary, to fully fill the canvas bounds. This process is async, so the function returns a Promise, which can be awaited or chained.
uCanvas
.setDataURL("...")
.then(() => uCanvas.download());
Wraps the ctx<CanvasRenderingContext2D>.fill()
method, allowing you to set one-off configuration for that fill call. Best used when you want to fill after multiple draw calls.
uCanvas
.polygon({
sides: 6,
center: { x: 430, y: 200 },
closed: true
}) // create open polygon
.polyline({
points: [ [0, 0 ], ... ],
closed: true
}) // draw a freehand shape
.fill({ color: "red" }) // fill with "red"
.stroke({
strokeSettings: { color: "blue" }
}) // stroke with blue
Wraps the ctx<CanvasRenderingContext2D>.fillRect()
method, allowing you to set one-off configuration for that fillRect call.
uCanvas.fillRect({
offset: { x: 100, y: 150 },
width: 200,
height: 100,
color: "#4c3758"
})
Wraps the ctx<CanvasRenderingContext2D>.beginPath()
method for drawing custom strokes
Wraps the ctx<CanvasRenderingContext2D>.stroke()
method, allowing you to set one-off configuration for that stroke call. Best used when you want to stroke after multiple draw calls.
Wraps the ctx<CanvasRenderingContext2D>.closePath()
method for drawing custom strokes
Draws an image (or canvas) to the UtilityCanvas, stretching the image to fit its width/height. You can also specify preserveAspect: true | "fill" | "fit"
which will call fillOrFitImage
instead and preserve the image's aspect ratio
const img = document.getElementById("img-1");
uCanvas
.fillImage(img, {operation: UtilityCanvas.COMPOSITE.BEHIND }) // draw image to canvas behind existing content
Like fillImage
, this method draws an image to the UtilityCanvas, but it preserves either the image's aspect ratio or a custom ratio. You can also specify the alignment anchors, offset, and margin
const img = document.getElementById("img-1");
uCanvas
.fillOrFitImage(img, {
fill: false, // when true, scale the image to cover the entire canvas (potentially with overhang)
aspect: 2, // set custom aspect ratio [height/width] (default is calculated from image)
anchors: { x: "center", y: "top" }, // align the image, centering horizontally, and aligning the top edge
offset: { x: 0, y: 100 }, // move image 100px down from top edge
margin: 25 // basically adds a frame of negative space to the image. You can also specify an object with different t (top), l (left), r (right), and b (bottom) margins
})
This method allows for tiling an image. You can also customize the tiling with horizontal or vertical staggering, rotation, alignment anchors, offset, and margin
const img = document.getElementById("img-1");
uCanvas
.fillImagePattern(img, {
anchors: { x: "center", y: "center" }, // default alignment, the middle of your pattern will be centered
offset: { x: 100, y: 0 }, // offset from your alignment
repeat: { x: 7, y: 9 }, // specify how many times the img should repeat in both directions (default will calculate how many are needed to fill x and y based on image size and rotation)
margin: { x: 10, y: 10 }, // frame of negative space around each tile
rotation: Math.PI / 4, // rotate entire pattern
stagger: 'x', // staggering offsets each other row to create a brick-like pattern in x or y direction
operation: UtilityCanvas.COMPOSITE.BEHIND // can still specify one-off operation setting
})
This method draws an image to the canvas, allowing you to customize the placement, rotation, and scale of the image.
const img = document.getElementById("img-1");
uCanvas
.drawImage(img, {
center: { x: 300, y: 400 }, // center point
rotation: Math.PI / 3, // default = 0
scale: 0.3 // image will be drawn at 30% of its naturalWidth/Height
})
Rather than specifying a scale like drawImage
, this method allows you to set absolute measurements for your image.
const img = document.getElementById("img-1");
uCanvas
.drawImageWithDimensions(img, {
center: { x: 300, y: 400 }, // center point
rotation: Math.PI / 3, // default = 0
width: 200, // specify fixed width
height: 250 // specify fixed height
})
Wraps the ctx<CanvasRenderingContext2D>.rect()
method, allowing you to customize the one-off configuration settings
uCanvas
.rect({
offset: { x: 0, y: 300 }, // position of top left corner of rect relative to the top left corner of the canvas
width: 100,
height: 200,
fill: "red"
})
Wraps the ctx<CanvasRenderingContext2D>.arc()
method, allowing you to customize the one-off configuration settings
uCanvas
.arc({
radius: 100, // default is half the minimum dimension (width/height)
center: { x: 100, y: 100 }, // position of the arc center (default is center of canvas)
startAngle: 0, // default
endAngle: 2 * Math.PI, // default
cc: false, // whether arc should be drawn countclockwise (default)
stroke: true
})
Wraps the ctx<CanvasRenderingContext2D>.arc()
method, allowing you to customize the one-off configuration settings
uCanvas
.ellipse({
radius: { x: 100, y: 50 }, // default is half the corresponding dimension
center: { x: 100, y: 100 }, // position of the ellipse center (default is center of canvas)
startAngle: 0, // default
endAngle: 2 * Math.PI, // default
cc: false, // whether arc should be drawn countclockwise (default)
rotation: Math.PI / 4, // default is 0
stroke: true
})
This method draws a rectangle with rounded corners. The corner radii are customizable.
uCanvas
.roundedRectangle({
width: 500,
height: 300,
radius: { tl: 20, tr: 10, bl: 15, br: 25},
// tl: topLeft, tr: topRight, bl: bottomLeft, br: bottomRight
// can also be a single number that is applied to all corners
fill: "red"
})
This method draws a multi-point line.
const points = [ [ 0, 0 ], [ 100, 0 ], [ 50, 50] ];
uCanvas
.polyline(points, { // must have at least 2 point arrays
closed: false, // should last point connect back to first point (default)
stroke: true
})
An abstraction of polyine
to create regular polygons. One of sideLength
or radius
must be specified, with radius specifying the distance from the center of the shape to each vertex (circumsribed circle)
uCanvas
.polygon({
sides: 6, // e.g. hexagon, must be greater than 2
radius: 100, // corresponds to a sideLength of 50 for a hexagon
sideLength: 50, // ignored because radius is specified
center: { x: 200, y: 200 }, // location of shape, defaults to center of canvas
closed: true, // should shape be closed (default)
fill: "yellow"
})
Another abstraction of polyline
for drawing a rotatable rectangle
uCanvas
.rectangle({
center: { x: 200, y: 200 }, // location of rectangle, defaults to center of canvas
width: 200,
height: 100,
rotation: Math.PI / 6, // default 0
closed: false, // should last point connect back to first point (default)
stroke: true
})
This method replaces a specified color on the canvas with transparent black pixels based on a threshold value. The higher the threshold value, the more colors will be replaced.
const img = document.getElementById("img-1");
uCanvas
.fillImage(img)
.chromaKey("#00ff00", 0.05)
// color can be a hex string or an object { r[0-255], g[0-255], b[0-255] }
// threshold will be clamped between 0.01 and 1