@szydlovski/canvas-utility
Advanced tools
Comparing version 2.0.0 to 2.1.0
{ | ||
"name": "@szydlovski/canvas-utility", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "simple canvas 2d utility - trimming, rotating, resizing", | ||
@@ -5,0 +5,0 @@ "main": "build/index.js", |
@@ -55,6 +55,99 @@ This library contains various utilities designed for working with the HTML5 Canvas. It facilitates operations like creating, copying, cropping, trimming, flipping, merging, resizing and rotating canvases. | ||
# Functional API | ||
The functional API allows non-destructive, immutable operations on the canvas. Note that in addition to canvases, all the functions accept images and offscreen canvases. | ||
## Types | ||
- Drawable - `HTMLImageElement | HTMLCanvasElement | OffscreenCanvas` | ||
- Dimensions - `{ width: number, height: number }` | ||
- DimensionsSource - `Dimensions | [number, number] | number` - an object with `width` and `height` properties, a `[width, height]` tuple or a single `number` (in which case it will be used for both width and height) | ||
- DrawCallback - `(ctx: CanvasRenderingContext2d) => void` | ||
## `createCanvas(source, callback)` | ||
Arguments: | ||
- source - `DimensionsSource` - used to determine dimensions for the created canvas | ||
- callback - `DrawCallback` - optional, allows you to immediately draw on the created canvas | ||
Returns: `HTMLCanvasElement`, the newly created canvas | ||
___ | ||
Creates a new canvas using the provided `dimensions`. Optionally, you can provide a callback which can be used to draw on the newly created canvas. | ||
Example useage: | ||
```js | ||
const c1 = createCanvas(500) // a 500 by 500 canvas | ||
const c2 = createCanvas([200,400]) // a 200 by 400 canvas | ||
const c3 = createCanvas({ width: 800, height: 1600 }) // a 800 by 1600 canvas | ||
const c4 = createCanvas(c2) // a 200 by 400 canvas | ||
const c5 = createCanvas(c3, ctx => ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)); // a 800 by 1600 canvas, filled with black pixels | ||
``` | ||
## `copyCanvas(canvas)` | ||
Arguments: | ||
- canvas - `Drawable` - the entity to be copied | ||
Returns: `HTMLCanvasElement`, a canvas with the copied entity | ||
___ | ||
Creates a copy of the provided `Drawable` by drawing it on a new, identically sized canvas. | ||
Example usage: | ||
```js | ||
const blackRect = createCanvas(c3, ctx => ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)); | ||
const blackRectCopy = copyCanvas(blackRect); | ||
console.log(blackRect !== blackRectCopy); // true | ||
``` | ||
## `trimCanvas(canvas)` | ||
Arguments: | ||
- canvas - `Drawable` - the entity to be trimmed | ||
Returns: `HTMLCanvasElement`, a canvas with the trimmed entity | ||
___ | ||
Trims the provided `Drawable` by copying its contents to a new canvas and removing empty lines of pixels. | ||
Example usage: | ||
```js | ||
const imgToTrim = createCanvas(500, ctx => ctx.fillRect(100, 100, 300, 300)); | ||
const trimmedImg = trimCanvas(imgToTrim); | ||
console.log(trimmedImg.width); // 300 | ||
console.log(trimmedImg.height); // 300 | ||
``` | ||
# Chainable Wrapper API | ||
The entire functional API is also available in a convenient, chainable wrapper, exported as `Canvas`, with methods named the same as the functional operations but without the `Canvas` suffix (i.e. `rotateCanvas` becomes `Canvas.rotate`). | ||
Example usage: | ||
```js | ||
const img = await loadImage('path/to/image.png'); | ||
const result = Canvas.fromImage(img) | ||
.trim() | ||
.resize({ width: 500 }) | ||
.crop('1:1') | ||
.rotate(45) | ||
.grayscale() | ||
.toElement(); // returns a canvas element | ||
``` | ||
# Changelog | ||
## [2.0.0] - 2021-08-01 | ||
## [2.1.0] - 2021-08-13 | ||
### Added | ||
- `extractPixelsFromCanvas` | ||
## [2.0.0] - 2021-08-09 | ||
Full TypeScript rewrite. | ||
@@ -61,0 +154,0 @@ |
import { createCanvas } from '../canvas-ops/createCanvas'; | ||
import { getImageData } from '../canvas-ops/getImageData'; | ||
import { Drawable } from '../types'; | ||
import { Drawable, PixelWithOrWithoutAlpha, RGBAComponent, RGBAPixel } from '../types'; | ||
type RGBAPixel = [number, number, number, number]; | ||
type RGBAComponent = 'r' | 'g' | 'b' | 'a'; | ||
export class ImageDataHandle { | ||
@@ -25,2 +24,16 @@ #rawImageData; | ||
} | ||
extractPixels<T extends boolean>(alpha: T): PixelWithOrWithoutAlpha<T>[] { | ||
return this.mapEachPixel(([r,g,b,a]) => alpha ? [r,g,b,a] : [r,g,b]) as PixelWithOrWithoutAlpha<T>[]; | ||
} | ||
mapEachPixel<T>(callback: (pixel: RGBAPixel) => T): T[] { | ||
const mapped: T[] = []; | ||
for (let y = 0; y < this.height; y++) { | ||
for (let x = 0; x < this.width; x++) { | ||
const position = y * this.width * 4 + x * 4; | ||
const [r,g,b,a] = this.data.slice(position, position + 4); | ||
mapped.push(callback([r,g,b,a])); | ||
} | ||
} | ||
return mapped; | ||
} | ||
_position(x: number, y: number) { | ||
@@ -27,0 +40,0 @@ return y * this.width * 4 + x * 4; |
@@ -14,2 +14,7 @@ export type Drawable = HTMLCanvasElement | HTMLImageElement | OffscreenCanvas; | ||
export type RGBAPixel = [number, number, number, number]; | ||
export type RGBPixel = [number, number, number]; | ||
export type RGBAComponent = 'r' | 'g' | 'b' | 'a'; | ||
export type PixelWithOrWithoutAlpha<T extends boolean> = T extends true ? RGBAPixel : RGBPixel; | ||
type Last<T extends any[]> = T extends [...infer R, infer L] ? L : never; | ||
@@ -16,0 +21,0 @@ export type SkipFirst<T extends any[]> = T extends [infer F, ...infer R] ? R : never; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
83452
90
1313
179
0