graphics-ts
Version:
A porting of purescript-{canvas, free-canvas, drawing} featuring fp-ts
896 lines (895 loc) • 25.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.renderTo = exports.bindWithContext = exports.bind = exports.withContext = exports.strokePath = exports.fillPath = exports.addColorStop = exports.translate = exports.transform = exports.strokeText = exports.strokeRect = exports.stroke = exports.setTransformMatrix = exports.setTransform = exports.setLineDash = exports.scale = exports.save = exports.rotate = exports.restore = exports.rect = exports.quadraticCurveTo = exports.putImageDataFull = exports.putImageData = exports.moveTo = exports.measureText = exports.lineTo = exports.isPointInStroke = exports.isPointInPath = exports.getTransform = exports.getLineDash = exports.getImageData = exports.fillText = exports.fillRect = exports.fill = exports.ellipse = exports.drawImageFull = exports.drawImageScale = exports.drawImage = exports.drawFocusIfNeeded = exports.createRadialGradient = exports.createPattern = exports.createLinearGradient = exports.createImageDataCopy = exports.createImageData = exports.closePath = exports.clip = exports.clearRect = exports.bezierCurveTo = exports.beginPath = exports.arcTo = exports.arc = exports.setTextBaseline = exports.getTextBaseline = exports.setTextAlign = exports.getTextAlign = exports.setStrokeStyle = exports.setShadowOffsetY = exports.setShadowOffsetX = exports.setShadowColor = exports.setShadowBlur = exports.setMiterLimit = exports.setLineWidth = exports.setLineJoin = exports.setLineDashOffset = exports.setLineCap = exports.setImageSmoothingEnabled = exports.setGlobalCompositeOperation = exports.setGlobalAlpha = exports.setFont = exports.getFont = exports.setFillStyle = exports.toDataURL = exports.setDimensions = exports.getDimensions = exports.setHeight = exports.getHeight = exports.setWidth = exports.getWidth = exports.getContext2D = exports.getCanvasElementById = exports.unsafeGetContext2D = exports.unsafeGetCanvasElementById = void 0;
/**
* The `Canvas` module contains all the functions necessary to interact with the HTML
* Canvas API. `graphics-ts` wraps all canvas operations in an `IO<A>` to allow for
* chaining multiple effectful calls to the HTML Canvas API.
*
* For example, taking the example of [drawing a triangle](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes) from the MDN Web Docs, the code
* without `graphics-ts` looks like this.
*
* ```ts
* const draw = () => {
* var canvas = document.getElementById('canvas')
*
* if (canvas.getContext) {
* var ctx = canvas.getContext('2d')
*
* ctx.beginPath();
* ctx.fillStyle = 'black'
* ctx.moveTo(75, 50)
* ctx.lineTo(100, 75)
* ctx.lineTo(100, 25)
* ctx.fill()
* }
* }
* ```
*
* With `graphics-ts`, the above code becomes
*
* ```ts
* import { error } from 'fp-ts/lib/Console'
* import { pipe } from 'fp-ts/lib/pipeable'
* import * as R from 'fp-ts-contrib/lib/ReaderIO'
* import * as C from 'graphics-ts/lib/Canvas'
* import * as Color from 'graphics-ts/lib/Color'
* import * as S from 'graphics-ts/lib/Shape'
*
* const canvasId = 'canvas'
*
* const triangle: C.Render<void> = C.fillPath(
* pipe(
* C.setFillStyle(pipe(Color.black, Color.toCss)),
* R.chain(() => C.moveTo(S.point(75, 50))),
* R.chain(() => C.lineTo(S.point(100, 75))),
* R.chain(() => C.lineTo(S.point(100, 25)))
* )
* )
*
* C.renderTo(canvasId, () => error(`[ERROR]: Unable to find canvas with id ${canvasId}`))(triangle)()
* ```
*
* While this may seem somewhat verbose compared to its non-functional counterpart above,
* the real power of the `Canvas` module is apparent when it is abstracted away by the
* `Drawing` module.
*
* Adapted from https://github.com/purescript-contrib/purescript-canvas.
*
* @since 1.0.0
*/
var R = require("fp-ts-contrib/lib/ReaderIO");
var IO = require("fp-ts/lib/IO");
var O = require("fp-ts/lib/Option");
var RA = require("fp-ts/lib/ReadonlyArray");
var Apply_1 = require("fp-ts/lib/Apply");
var function_1 = require("fp-ts/lib/function");
var pipeable_1 = require("fp-ts/lib/pipeable");
// -------------------------------------------------------------------------------------
// constructors
// -------------------------------------------------------------------------------------
/**
* **[UNSAFE]** Gets a canvas element by id.
*
* @category constructors
* @since 1.0.0
*/
exports.unsafeGetCanvasElementById = function (id) {
return document.getElementById(id);
};
/**
* **[UNSAFE]** Gets the 2D graphics context for a canvas element.
*
* @category constructors
* @since 1.0.0
*/
exports.unsafeGetContext2D = function (c) {
return c.getContext('2d');
};
/**
* Gets an canvas element by id, or `None` if the element does not exist or is not an
* instance of `HTMLCanvasElement`.
*
* @category constructors
* @since 1.0.0
*/
exports.getCanvasElementById = function (id) { return function () {
var canvas = exports.unsafeGetCanvasElementById(id);
return canvas instanceof HTMLCanvasElement ? O.some(canvas) : O.none;
}; };
// -------------------------------------------------------------------------------------
// combinators
// -------------------------------------------------------------------------------------
/**
* Gets the 2D graphics context for a canvas element.
*
* @category combinators
* @since 1.0.0
*/
exports.getContext2D = function (c) { return IO.of(exports.unsafeGetContext2D(c)); };
/**
* Gets the canvas width in pixels.
*
* @category combinators
* @since 1.0.0
*/
exports.getWidth = function (c) { return function () { return c.width; }; };
/**
* Sets the width of the canvas in pixels.
*
* @category combinators
* @since 1.0.0
*/
exports.setWidth = function (w) { return function (c) { return function () {
c.width = w;
return c;
}; }; };
/**
* Gets the canvas height in pixels.
*
* @category combinators
* @since 1.0.0
*/
exports.getHeight = function (c) { return function () { return c.height; }; };
/**
* Sets the height of the canvas in pixels.
*
* @category combinators
* @since 1.0.0
*/
exports.setHeight = function (h) { return function (c) { return function () {
c.height = h;
return c;
}; }; };
/**
* Gets the dimensions of the canvas in pixels.
*
* @category combinators
* @since 1.0.0
*/
exports.getDimensions = function (c) {
return Apply_1.sequenceS(IO.io)({ height: exports.getHeight(c), width: exports.getWidth(c) });
};
/**
* Sets the dimensions of the canvas in pixels.
*
* @category combinators
* @since 1.0.0
*/
exports.setDimensions = function (d) {
return pipeable_1.pipe(exports.setWidth(d.width), R.chain(function () { return exports.setHeight(d.height); }));
};
/**
* Create a data URL for the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.toDataURL = function (c) { return function () { return c.toDataURL(); }; };
/**
* Sets the current fill style for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setFillStyle = function (s) { return function (ctx) { return function () {
ctx.fillStyle = s;
return ctx;
}; }; };
/**
* Gets the current font.
*
* @category combinators
* @since 1.0.0
*/
exports.getFont = function (ctx) { return function () { return ctx.font; }; };
/**
* Sets the current font.
*
* @category combinators
* @since 1.0.0
*/
exports.setFont = function (f) { return function (ctx) { return function () {
ctx.font = f;
return ctx;
}; }; };
/**
* Sets the current global alpha for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setGlobalAlpha = function (a) { return function (ctx) { return function () {
ctx.globalAlpha = a;
return ctx;
}; }; };
/**
* Sets the current global composite operation type for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setGlobalCompositeOperation = function (gco) { return function (ctx) { return function () {
ctx.globalCompositeOperation = gco;
return ctx;
}; }; };
/**
* Sets the current image smoothing property for the canvas context. Determines whether scaled images are smoothed
* (`true`, default) or not (`false`).
*
* @category combinators
* @since 1.0.0
*/
exports.setImageSmoothingEnabled = function (v) { return function (ctx) { return function () {
ctx.imageSmoothingEnabled = v;
return ctx;
}; }; };
/**
* Sets the current line cap type for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setLineCap = function (c) { return function (ctx) { return function () {
ctx.lineCap = c;
return ctx;
}; }; };
/**
* Sets the current line dash offset, or "phase", for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setLineDashOffset = function (o) { return function (ctx) { return function () {
ctx.lineDashOffset = o;
return ctx;
}; }; };
/**
* Sets the current line join type for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setLineJoin = function (j) { return function (ctx) { return function () {
ctx.lineJoin = j;
return ctx;
}; }; };
/**
* Sets the current line width for the canvas context in pixels.
*
* @category combinators
* @since 1.0.0
*/
exports.setLineWidth = function (w) { return function (ctx) { return function () {
ctx.lineWidth = w;
return ctx;
}; }; };
/**
* Sets the current miter limit for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setMiterLimit = function (l) { return function (ctx) { return function () {
ctx.miterLimit = l;
return ctx;
}; }; };
/**
* Sets the current shadow blur radius for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setShadowBlur = function (b) { return function (ctx) { return function () {
ctx.shadowBlur = b;
return ctx;
}; }; };
/**
* Sets the current shadow color for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setShadowColor = function (c) { return function (ctx) { return function () {
ctx.shadowColor = c;
return ctx;
}; }; };
/**
* Sets the current shadow x-offset for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setShadowOffsetX = function (ox) { return function (ctx) { return function () {
ctx.shadowOffsetX = ox;
return ctx;
}; }; };
/**
* Sets the current shadow y-offset for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setShadowOffsetY = function (oy) { return function (ctx) { return function () {
ctx.shadowOffsetY = oy;
return ctx;
}; }; };
/**
* Sets the current stroke style for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setStrokeStyle = function (s) { return function (ctx) { return function () {
ctx.strokeStyle = s;
return ctx;
}; }; };
/**
* Gets the current text alignment.
*
* @category combinators
* @since 1.0.0
*/
exports.getTextAlign = function (ctx) { return function () { return ctx.textAlign; }; };
/**
* Sets the current text alignment.
*
* @category combinators
* @since 1.0.0
*/
exports.setTextAlign = function (ta) { return function (ctx) { return function () {
ctx.textAlign = ta;
return ctx;
}; }; };
/**
* Gets the current text baseline.
*
* @category combinators
* @since 1.0.0
*/
exports.getTextBaseline = function (ctx) { return function () { return ctx.textBaseline; }; };
/**
* Sets the current text baseline.
*
* @category combinators
* @since 1.0.0
*/
exports.setTextBaseline = function (tb) { return function (ctx) { return function () {
ctx.textBaseline = tb;
return ctx;
}; }; };
/**
* Render an arc.
*
* @category combinators
* @since 1.0.0
*/
exports.arc = function (a) { return function (ctx) { return function () {
ctx.arc(a.x, a.y, a.r, a.start, a.end, a.anticlockwise);
return ctx;
}; }; };
/**
* Render an arc that is automatically connected to the path's latest point.
*
* @category combinators
* @since 1.0.0
*/
exports.arcTo = function (x1, y1, x2, y2, r) { return function (ctx) { return function () {
ctx.arcTo(x1, y1, x2, y2, r);
return ctx;
}; }; };
/**
* Begin a path on the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.beginPath = function (ctx) { return function () {
ctx.beginPath();
return ctx;
}; };
/**
* Draw a cubic Bézier curve.
*
* @category combinators
* @since 1.0.0
*/
exports.bezierCurveTo = function (cpx1, cpy1, cpx2, cpy2, x, y) { return function (ctx) { return function () {
ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y);
return ctx;
}; }; };
/**
* Set the pixels in the specified rectangle back to transparent black.
*
* @category combinators
* @since 1.0.0
*/
exports.clearRect = function (r) { return function (ctx) { return function () {
ctx.clearRect(r.x, r.y, r.width, r.height);
return ctx;
}; }; };
/**
* Clip the current path on the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.clip = function (f, p) { return function (ctx) { return function () {
if (typeof p !== 'undefined') {
ctx.clip(p, f);
}
else if (typeof f !== 'undefined') {
ctx.clip(f);
}
else {
ctx.clip();
}
return ctx;
}; }; };
/**
* Closes the current canvas path.
*
* @category combinators
* @since 1.0.0
*/
exports.closePath = function (ctx) { return function () {
ctx.closePath();
return ctx;
}; };
/**
* Gets `ImageData` for the specified rectangle.
*
* @category combinators
* @since 1.0.0
*/
exports.createImageData = function (sw, sh) { return function (ctx) { return function () {
return ctx.createImageData(sw, sh);
}; }; };
/**
* Creates a copy of an existing `ImageData` object.
*
* @category combinators
* @since 1.0.0
*/
exports.createImageDataCopy = function (data) { return function (ctx) { return function () {
return ctx.createImageData(data);
}; }; };
/**
* Creates a linear `CanvasGradient` object.
*
* @category combinators
* @since 1.0.0
*/
exports.createLinearGradient = function (x0, y0, x1, y1) { return function (ctx) { return function () { return ctx.createLinearGradient(x0, y0, x1, y1); }; }; };
/**
* Creates a new canvas pattern (repeatable image).
*
* @category combinators
* @since 1.0.0
*/
exports.createPattern = function (s, r) { return function (ctx) { return function () { return O.fromNullable(ctx.createPattern(s, r)); }; }; };
/**
* Creates a radial `CanvasGradient` object.
*
* @category combinators
* @since 1.0.0
*/
exports.createRadialGradient = function (x0, y0, r0, x1, y1, r1) { return function (ctx) { return function () {
return ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);
}; }; };
/**
* Draws a focus ring around the current or given path, if the specified element is focused.
*
* @category combinators
* @since 1.0.0
*/
exports.drawFocusIfNeeded = function (el, p) { return function (ctx) { return function () {
if (typeof p !== 'undefined') {
ctx.drawFocusIfNeeded(p, el);
}
else {
ctx.drawFocusIfNeeded(el);
}
return ctx;
}; }; };
/**
* Render an image.
*
* @category combinators
* @since 1.0.0
*/
exports.drawImage = function (s, ox, oy) { return function (ctx) { return function () {
ctx.drawImage(s, ox, oy);
return ctx;
}; }; };
/**
* Draws an image to the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.drawImageScale = function (s, ox, oy, w, h) { return function (ctx) { return function () {
ctx.drawImage(s, ox, oy, w, h);
return ctx;
}; }; };
/**
* Draws an image to the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.drawImageFull = function (s, ox, oy, w, h, cox, coy, ciw, cih) { return function (ctx) { return function () {
ctx.drawImage(s, ox, oy, w, h, cox, coy, ciw, cih);
return ctx;
}; }; };
/**
* Render an ellipse.
*
* @category combinators
* @since 1.0.0
*/
exports.ellipse = function (e) { return function (ctx) { return function () {
ctx.ellipse(e.x, e.y, e.rx, e.ry, e.rotation, e.start, e.end, e.anticlockwise);
return ctx;
}; }; };
/**
* Fill the current path on the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.fill = function (f, p) { return function (ctx) { return function () {
if (typeof p !== 'undefined') {
ctx.fill(p, f);
}
else if (typeof f !== 'undefined') {
ctx.fill(f);
}
else {
ctx.fill();
}
return ctx;
}; }; };
/**
* Render a filled rectangle.
*
* @category combinators
* @since 1.0.0
*/
exports.fillRect = function (r) { return function (ctx) { return function () {
ctx.fillRect(r.x, r.y, r.width, r.height);
return ctx;
}; }; };
/**
* Render filled text.
*
* @category combinators
* @since 1.0.0
*/
exports.fillText = function (t, x, y, mw) { return function (ctx) { return function () {
if (typeof mw !== 'undefined') {
ctx.fillText(t, x, y, mw);
}
else {
ctx.fillText(t, x, y);
}
return ctx;
}; }; };
/**
* Gets the image data for the specified portion of the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.getImageData = function (r) { return function (ctx) { return function () {
return ctx.getImageData(r.x, r.y, r.width, r.height);
}; }; };
/**
* Gets the current line dash pattern for the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.getLineDash = function (ctx) { return function () { return RA.fromArray(ctx.getLineDash()); }; };
/**
* Gets the current transformation matrix being applied to the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.getTransform = function (ctx) { return function () { return ctx.getTransform(); }; };
/**
* Determines if the specified point is contained in the current path.
*
* @category combinators
* @since 1.0.0
*/
exports.isPointInPath = function (p, rule, path) { return function (ctx) { return function () {
if (typeof path !== 'undefined') {
return ctx.isPointInPath(path, p.x, p.y, rule);
}
else {
return typeof rule !== 'undefined' ? ctx.isPointInPath(p.x, p.y, rule) : ctx.isPointInPath(p.x, p.y);
}
}; }; };
/**
* Determines if the specified point is inside the area contained by the stroking of a path.
*
* @category combinators
* @since 1.0.0
*/
exports.isPointInStroke = function (p, path) { return function (ctx) { return function () {
return typeof path !== 'undefined' ? ctx.isPointInStroke(path, p.x, p.y) : ctx.isPointInStroke(p.x, p.y);
}; }; };
/**
* Move the canvas path to the specified point while drawing a line segment.
*
* @category combinators
* @since 1.0.0
*/
exports.lineTo = function (p) { return function (ctx) { return function () {
ctx.lineTo(p.x, p.y);
return ctx;
}; }; };
/**
* Get the text measurements for the specified text.
*
* @category combinators
* @since 1.0.0
*/
exports.measureText = function (t) { return function (ctx) { return function () { return ctx.measureText(t); }; }; };
/**
* Move the canvas path to the specified point without drawing a line segment.
*
* @category combinators
* @since 1.0.0
*/
exports.moveTo = function (p) { return function (ctx) { return function () {
ctx.moveTo(p.x, p.y);
return ctx;
}; }; };
/**
* Sets the image data for the specified portion of the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.putImageData = function (data, dx, dy) { return function (ctx) { return function () {
ctx.putImageData(data, dx, dy);
return ctx;
}; }; };
/**
* Sets the image data for the specified portion of the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.putImageDataFull = function (data, dx, dy, dirtyX, dirtyY, dirtyW, dirtyH) { return function (ctx) { return function () {
ctx.putImageData(data, dx, dy, dirtyX, dirtyY, dirtyW, dirtyH);
return ctx;
}; }; };
/**
* Draws a quadratic Bézier curve.
*
* @category combinators
* @since 1.0.0
*/
exports.quadraticCurveTo = function (cpx, cpy, x, y) { return function (ctx) { return function () {
ctx.quadraticCurveTo(cpx, cpy, x, y);
return ctx;
}; }; };
/**
* Render a rectangle.
*
* @category combinators
* @since 1.0.0
*/
exports.rect = function (r) { return function (ctx) { return function () {
ctx.rect(r.x, r.y, r.width, r.height);
return ctx;
}; }; };
/**
* Restore the previous canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.restore = function (ctx) { return function () {
ctx.restore();
return ctx;
}; };
/**
* Apply rotation to the current canvas context transform.
*
* @category combinators
* @since 1.0.0
*/
exports.rotate = function (a) { return function (ctx) { return function () {
ctx.rotate(a);
return ctx;
}; }; };
/**
* Save the current canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.save = function (ctx) { return function () {
ctx.save();
return ctx;
}; };
/**
* Apply scale to the current canvas context transform.
*
* @category combinators
* @since 1.0.0
*/
exports.scale = function (x, y) { return function (ctx) { return function () {
ctx.scale(x, y);
return ctx;
}; }; };
/**
* Sets the current line dash pattern used when stroking lines.
*
* @category combinators
* @since 1.0.0
*/
exports.setLineDash = function (ss) { return function (ctx) { return function () {
ctx.setLineDash(RA.toArray(ss));
return ctx;
}; }; };
/**
* Resets the current transformation to the identity matrix, and then applies the transform specified
* to the current canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setTransform = function (a, b, c, d, e, f) { return function (ctx) { return function () {
ctx.setTransform(a, b, c, d, e, f);
return ctx;
}; }; };
/**
* Resets the current transformation to the identity matrix, and then applies the transform specified
* to the current canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.setTransformMatrix = function (matrix) { return function (ctx) { return function () {
ctx.setTransform(matrix);
return ctx;
}; }; };
/**
* Stroke the current path on the canvas.
*
* @category combinators
* @since 1.0.0
*/
exports.stroke = function (p) { return function (ctx) { return function () {
if (typeof p !== 'undefined') {
ctx.stroke(p);
}
else {
ctx.stroke();
}
return ctx;
}; }; };
/**
* Render a stroked rectangle.
*
* @category combinators
* @since 1.0.0
*/
exports.strokeRect = function (r) { return function (ctx) { return function () {
ctx.strokeRect(r.x, r.y, r.width, r.height);
return ctx;
}; }; };
/**
* Render stroked text.
*
* @category combinators
* @since 1.0.0
*/
exports.strokeText = function (t, x, y, mw) { return function (ctx) { return function () {
if (typeof mw !== 'undefined') {
ctx.strokeText(t, x, y, mw);
}
else {
ctx.strokeText(t, x, y);
}
return ctx;
}; }; };
/**
* Apply the specified transformation matrix to the canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.transform = function (m11, m12, m21, m22, m31, m32) { return function (ctx) { return function () {
ctx.transform(m11, m12, m21, m22, m31, m32);
return ctx;
}; }; };
/**
* Translate the current canvas context transform.
*
* @category combinators
* @since 1.0.0
*/
exports.translate = function (x, y) { return function (ctx) { return function () {
ctx.translate(x, y);
return ctx;
}; }; };
/**
* Add a single color stop to a `CanvasGradient` object.
*
* @category combinators
* @since 1.0.0
*/
exports.addColorStop = function (o, c) { return function (g) { return function () {
g.addColorStop(o, c);
return g;
}; }; };
/**
* Convenience function for drawing a filled path.
*
* @category combinators
* @since 1.0.0
*/
exports.fillPath = function (f) {
return pipeable_1.pipe(exports.beginPath, R.chain(function () { return f; }), R.chainFirst(function () { return exports.fill(); }));
};
/**
* Convenience function for drawing a stroked path.
*
* @category combinators
* @since 1.0.0
*/
exports.strokePath = function (f) {
return pipeable_1.pipe(exports.beginPath, R.chain(function () { return f; }), R.chainFirst(function () { return exports.stroke(); }));
};
/**
* A convenience function which allows for running an action while preserving the existing
* canvas context.
*
* @category combinators
* @since 1.0.0
*/
exports.withContext = function (f) {
return pipeable_1.pipe(exports.save, R.chain(function () { return f; }), R.chainFirst(function () { return exports.restore; }));
};
// TODO: remove in version 2.0.0
/**
* Binds an event handler to the canvas element.
*
* @deprecated since 1.1.0
* @category combinators
* @since 1.0.0
*/
exports.bind = function (t, f) { return function (c) { return function () {
c.addEventListener(t, f);
return c;
}; }; };
// TODO: rename in version 2.0.0
/**
* Binds an event handler to the canvas element.
*
* @category combinators
* @since 1.1.0
*/
exports.bindWithContext = function (type, f) { return function (ctx) { return function () {
ctx.canvas.addEventListener(type, function (e) { return f(e)(ctx)(); });
return ctx;
}; }; };
// -------------------------------------------------------------------------------------
// utils
// -------------------------------------------------------------------------------------
/**
* Executes a `Render` effect for a canvas with the specified `canvasId`, or `onCanvasNotFound()` if a canvas with
* the specified `canvasId` does not exist.
*
* @since 1.0.0
*/
exports.renderTo = function (canvasId, onCanvasNotFound) { return function (r) {
return pipeable_1.pipe(exports.getCanvasElementById(canvasId), IO.chain(O.fold(onCanvasNotFound, function_1.flow(exports.getContext2D, IO.chain(r)))));
}; };