Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

curtail

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

curtail - npm Package Compare versions

Comparing version 1.0.2 to 2.0.0

changelog.md

449

curtail.js
'use strict'
import * as extract from './extract.js';
import * as math from './math.js';
import * as utils from './utils.js';
/**
* Curtail is a pure JavaScript in browser canvas-based image manipulation tool.
* Curtail is a pure JavaScript image manipulation tool.
*/
/**
* Crop an image to a specified size by providing the start location of the crop and
* the dimensions that the product should have.
*
* @since 0.1.0
*
* @param {string} path The path to the image to crop.
* @param {number} x The horizontal location in the original image to begin the crop.
* @param {number} y The vertical location in the original image to being the crop.
* @param {number} width The width of the final cropped image.
* @param {number} height The height of of the final cropped image.
* @param {Object} [options]
* @param {boolean} [options.autoDownload=false] Indicates whether the image should download after the cropping is complete or not.
* @param {string} [options.crossOrigin=null] Sets the cross-origin property of images originating from external sources.
*
* @returns {Promize<HTMLImageElement>} Returns the newly cropped image as an image element.
*/
export class Curtail {
export function crop(path, x, y, width, height, options = {}) {
/**
* @param {Object} [options] Options used to alter the functionality of Curtail.
* @param {boolean} [autoDownload=false] Indicates whether the new image will be queued to download automatically after it is transformed.
* @param {string} [crossOrigin=null] Set a cross-origin property for images loaded from non-local sources.
*/
constructor(options = {}) {
const _options = Object.assign({
/**
* Combine the user options with the defaults for any options not set.
*
* @prop {Object}
* @readonly
*/
this._options = Object.assign({
autoDownload: false,
/**
* Indicates whether the image should auto-download after the edit.
*
* @prop {boolean}
*/
autoDownload: false,
crossOrigin: null
/**
* Sets a cross-origin property for the images used.
*
* @prop {string}
*/
crossOrigin: null
}, options);
}, options);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
/**
* Used when converting an image to another format, it has to be from the
* following supported formats.
*
* @prop {Object}
*/
this.FORMAT = {
const fileInfo = utils.extractFileInfo(path);
PNG: { ext: 'png', transparent: true },
const originalImage = new Image();
JPG: { ext: 'jpg', transparent: false },
return new Promise((resolve, reject) => {
GIF: { ext: 'gif', transparent: false },
originalImage.addEventListener('load', function loadImage() {
BMP: { ext: 'bmp', transparent: false },
canvas.width = width;
canvas.height = height;
WEBP: { ext: 'webp', transparent: true },
ctx.drawImage(originalImage, x, y, width, height, 0, 0, width, height);
PDF: { ext: 'pdf', transparent: true },
const croppedImage = new Image();
};
croppedImage.addEventListener('load', function loadCroppedImage() {
}
if (_options.autoDownload) {
/**
* Crop an image down to a specified size by providing the location to being cropping
* the image and the dimensions of the new desired image.
*
* @since 0.1.0
*
* @param {string} src The path to the image to crop.
* @param {number} x The x location in the original image to begin the crop.
* @param {number} y The y location in the original image to begin the crop.
* @param {number} width The desired width for the cropped image.
* @param {number} height The desired height for the cropped image.
*
* @returns {Promise<HTMLImageElement>} The newly cropped image.
*/
crop(src, x, y, width, height) {
const imageLink = document.createElement('a');
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
imageLink.href = croppedImage.src;
imageLink.download = fileInfo.name + '.' + fileInfo.ext;
const nameIndex = src.lastIndexOf('/') + 1 || 0;
const extIndex = src.lastIndexOf('.');
imageLink.click();
const srcName = src.slice(nameIndex, extIndex);
const srcExt = src.slice(extIndex + 1);
}
const originalImage = new Image();
croppedImage.removeEventListener('load', loadCroppedImage);
return new Promise((resolve, reject) => {
resolve(croppedImage);
originalImage.onload = () => {
});
canvas.width = width;
canvas.height = height;
croppedImage.addEventListener('error', function loadCroppedImageError(err) {
ctx.drawImage(originalImage, x, y, width, height, 0, 0, width, height);
croppedImage.removeEventListener('error', loadCroppedImage);
const croppedImage = new Image();
reject(err);
croppedImage.onload = () => {
});
if (this._options.autoDownload) {
croppedImage.src = canvas.toDataURL(`image/${fileInfo.ext}`).replace(`image/${fileInfo.ext}`, 'image/octet-stream');
let img = document.createElement('a');
});
img.href = croppedImage.src;
img.download = srcName + '.' + srcExt;
originalImage.addEventListener('error', function loadImageError(err) {
img.click();
originalImage.removeEventListener('error', loadImageError);
}
reject(err);
resolve(croppedImage);
});
originalImage.src = path;
if (_options.crossOrigin) originalImage.crossOrigin = _options.crossOrigin;
});
}
/**
* Convert an image from one format to another format.
*
* @since 1.0.0
*
* @param {string} path The path to the image to convert to another format.
* @param {string} format The new format for the image.
* @param {Object} [options]
* @param {boolean} [options.autoDownload=false] Indicates whether the image should download after the cropping is complete or not.
* @param {string} [options.crossOrigin=null] Sets the cross-origin property of images originating from external sources.
*
* @returns {Promise<HTMLImageElement>} Returns the newly formatted image as an image element.
*/
export function convert(path, format, options = {}) {
const _options = Object.assign({
autoDownload: false,
crossOrigin: null
}, options);
const nonTransparentFormats = ['jpg', 'jpeg', 'gif', 'bmp'];
const fileInfo = utils.extractFileInfo(path);
if (fileInfo.ext === format) return;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const originalImage = new Image();
return new Promise((resolve, reject) => {
originalImage.addEventListener('load', function loadImage() {
canvas.width = originalImage.width;
canvas.height = originalImage.height;
if (nonTransparentFormats.includes(format)) {
ctx.fillStyle = '#FFF';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(originalImage, 0, 0);
const convertedImage = new Image();
convertedImage.addEventListener('load', function loadConvertedImage() {
if (_options.autoDownload) {
const imageLink = document.createElement('a');
imageLink.href = convertedImage.src;
imageLink.download = fileInfo.name + '.' + format;
imageLink.click();
}
croppedImage.onerror = (err) => reject(err);
convertedImage.removeEventListener('load', loadConvertedImage);
croppedImage.src = canvas.toDataURL(`image/${srcExt}`).replace(`image/${srcExt}`, 'image/octet-stream');
resolve(convertedImage);
};
});
originalImage.onerror = (err) => reject(err);
convertedImage.addEventListener('error', function loadConvertedImageError(err) {
originalImage.src = src;
if (this._options.crossOrigin) originalImage.crossOrigin = this._options.crossOrigin;
convertedImage.removeEventListener('load', loadConvertedImageError);
reject(err);
});
convertedImage.src = canvas.toDataURL(`image/${format}`);
originalImage.removeEventListener('load', loadImage);
});
}
originalImage.addEventListener('error', function loadImageError(err) {
/**
* Convert an image from one format to another format, eg png to jpg.
*
* @since 1.0.0
*
* @param {string} src The path to the image to convert.
* @param {FORMAT} format The format, from the `curtail.FORMAT` object to convert the image to.
*
* @returns {Promise<HTMLImageElement>} The newly converted image.
*/
convert(src, format) {
originalImage.removeEventListener('load', loadImageError);
const fileInfo = extract.getFileInfo(src);
reject(err);
if (fileInfo.ext === format.ext) {
});
console.warn('Image is already in desired format.');
return;
originalImage.src = path;
}
if (_options.crossOrigin) originalImage.crossOrigin = _options.crossOrigin;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
});
const originalImage = new Image();
}
return new Promise((resolve, reject) => {
/**
* Resize an image to a new dimension.
*
* @since 1.0.0
*
* @param {string} path The path to the image to resize.
* @param {string} dimension Which dimension to resize, either width or height. Keep in mind that if you're preserving the aspect ratio, the other will resize accordingly.
* @param {number} size The new size to make the specified dimension.
* @param {Object} [options]
* @param {boolean} [options.preserveAspectRatio=true] Indicates whether the width and height will resize together to preserve the aspect ratio of the image.
* @param {boolean} [options.autoDownload=false] Indicates whether the image should download after the cropping is complete or not.
* @param {string} [options.crossOrigin=null] Sets the cross-origin property of images originating from external sources.
*
* @returns {Promise<HTMLImageElement>} Returns the newly resized image as an image element.
*/
export function resize(path, dimension, size, options = {}) {
originalImage.onload = () => {
const _options = Object.assign({
canvas.width = originalImage.width;
canvas.height = originalImage.height;
preserveAspectRatio: true,
if (!format.transparent) {
autoDownload: false,
ctx.fillStyle = '#FFF';
ctx.fillRect(0, 0, canvas.width, canvas.height);
crossOrigin: null
}
}, options);
ctx.drawImage(originalImage, 0, 0);
const originalImage = new Image();
const newImage = new Image();
return new Promise((resolve, reject) => {
newImage.onload = () => {
originalImage.addEventListener('load', function loadImage() {
if (this._options.autoDownload) {
const aspectRatio = utils.simplify(originalImage.width, originalImage.height);
let img = document.createElement('a');
if (dimension === 'width') {
img.href = newImage.src;
img.download = fileInfo.name + '.' + format.ext;
originalImage.width = size;
img.click();
if (_options.preserveAspectRatio) originalImage.height = Math.round((aspectRatio.denominator / aspectRatio.numerator) * size);
}
}
else if (dimension === 'height') {
resolve(newImage);
originalImage.height = size;
};
if (_options.preserveAspectRatio) originalImage.width = Math.round((aspectRatio.numerator / aspectRatio.denominator) * size);
newImage.onerror = (err) => reject(err);
}
newImage.src = canvas.toDataURL(`image/${format.ext}`);
originalImage.removeEventListener('load', loadImage);
};
if (_options.autoDownload) {
originalImage.onerror = (err) => reject(err);
const imageLink = document.createElement('a');
originalImage.src = src;
if (this._options.crossOrigin) originalImage.crossOrigin = this._options.crossOrigin;
imageLink.href = convertedImage.src;
imageLink.download = fileInfo.name + '.' + format;
imageLink.click();
}
resolve(originalImage);
});
}
originalImage.addEventListener('error', function loadImageError(err) {
/**
* Resize an image.
*
* The aspect ratio is automatically preserved when resizing an image unless
* the `preserveAspectRatio` parameter is set to false.
*
* @since 0.1.0
*
* @param {string} src The path to the image to convert.
* @param {string} dimsension Whether you want to resize the width or height of the image.
* @param {number} size The new size to make the specified dimension in pixels.
* @param {boolean} [preserveAspectRatio=true] Indicates whether the width and height should resize together to preserve the aspect ratio of the image.
*
* @returns {Promise<HTMLImageElement>} The newly resized image.
*/
resize(src, dimension, size, preserveAspectRatio = true) {
originalImage.removeEventListener('error', loadImageError);
const image = new Image();
reject(err);
return new Promise((resolve, reject) => {
});
image.onload = () => {
originalImage.src = path;
const aspectRatio = math.simplify(image.width, image.height);
if (_options.crossOrigin) originalImage.crossOrigin = _options.crossOrigin;
if (dimension === 'width') {
});
image.width = size;
}
if (preserveAspectRatio) image.height = Math.round((aspectRatio[1] / aspectRatio[0]) * size);
/**
* Adds the specified amount of padding around an image.
*
* Note that the padding will not be even on images that are not square.
*
* @since 2.0.0
*
* @param {string} path The path to the image to add padding to.
* @param {number} padding The amount of padding to add to the image.
* @param {Object} [options]
* @param {string} [options.paddingColor='transparent'] The color that the padding will be. This value can be any valid CSS color value such as white or #FFFFFF.
* @param {boolean} [options.autoDownload=false] Indicates whether the image should download after the cropping is complete or not.
* @param {string} [options.crossOrigin=null] Sets the cross-origin property of images originating from external sources.
*
* @returns {Promise<HTMLImageElement>} Returns the newly padded image as an image element.
*/
export function pad(path, padding, options = {}) {
}
const _options = Object.assign({
else if (dimension === 'height') {
paddingColor: 'transparent',
image.height = size;
autoDownload: false,
if (preserveAspectRatio) image.width = Math.round((aspectRatio[0] / aspectRatio[1]) * size);
crossOrigin: null
}, options);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const fileInfo = utils.extractFileInfo(path);
const originalImage = new Image();
return new Promise((resolve, reject) => {
originalImage.addEventListener('load', function loadImage() {
canvas.width = originalImage.width + (padding * 2);
canvas.height = originalImage.height + (padding * 2);
if (_options.paddingColor !== 'transparent') {
ctx.fillStyle = _options.paddingColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(originalImage, canvas.width / 2 - originalImage.width / 2, canvas.height / 2 - originalImage.height / 2, originalImage.width, originalImage.height);
const paddedImage = new Image();
paddedImage.addEventListener('load', function loadPaddedImage() {
if (_options.autoDownload) {
const imageLink = document.createElement('a');
imageLink.href = paddedImage.src;
imageLink.download = fileInfo.name + '.' + format;
imageLink.click();
}
resolve(image);
paddedImage.removeEventListener('load', loadPaddedImage);
};
resolve(paddedImage);
image.onerror = (err) => reject(err);
});
image.src = src;
if (this._options.crossOrigin) image.crossOrigin = this._options.crossOrigin;
paddedImage.addEventListener('error', function loadPaddedImageError(err) {
paddedImage.removeEventListener('load', loadPaddedImageError);
reject(err);
});
paddedImage.src = canvas.toDataURL(`image/${fileInfo.ext}`);
originalImage.removeEventListener('load', loadImage);
});
}
originalImage.addEventListener('error', function loadImageError(err) {
originalImage.removeEventListener('error', loadImageError);
reject(err);
});
originalImage.src = path;
if (_options.crossOrigin) originalImage.crossOrigin = _options.crossOrigin;
});
}
'use strict'
/**
* The functions in extract deal with getting information from the
* src path such as file name or file extension.
* Extract the name of the file and the file's extension from the provided file path.
*
* @since 1.0.0
*/
/**
* Extract the file name and extension from the provided src path.
*
* @since 1.0.0
* @param {string} path The user provided path to the image file.
*
* @param {string} src The path to the image file.
*
* @returns {Object} An object containing the file's name and extension.
* @returns {Object} Returns an object with the file name and extension as properties and the results as the values.
*/
function getFileInfo(src) {
export function extractFileInfo(path) {

@@ -24,14 +17,15 @@ let nameIndex = 0;

let fileInfo = {
name: null,
ext: null
};
const fileInfo = { name: null, ext: null };
if (src.lastIndexOf('/') > -1) nameIndex = src.lastIndexOf('/');
if (path.lastIndexOf('/') > -1) {
extIndex = src.lastIndexOf('.');
nameIndex = path.lastIndexOf('/');
fileInfo.name = src.slice(nameIndex + 1, extIndex);
fileInfo.ext = src.slice(extIndex + 1);
}
extIndex = path.lastIndexOf('.');
fileInfo.name = path.slice(nameIndex + 1, extIndex);
fileInfo.ext = path.slice(extIndex + 1);
return fileInfo;

@@ -42,23 +36,16 @@

/**
* The functions in math deal with any mathematical operations not
* supported by native JavaScript.
* Simplify a fraction by using the greatest common divisor method.
*
* @since 0.1.0
*/
/**
* Simplify a fraction using the greatest common divisor.
*
* @since 0.1.0
* @param {number} numerator The top number of the fraction to simplify.
* @param {number} denominator The bottom number of the fraction to simplify.
*
* @param {number} numerator The top number of the original fraction.
* @param {number} denominator The bottom number of the original fraction.
*
* @returns {Array} An array consisting of the two values representing the numerator and denominator of the simplified fraction.
* @returns {Object} Returns an object with the numerator/denominator as properties and the simplified results as the values.
*/
function simplify(numerator, denominator) {
export function simplify(numerator, denominator) {
const num = gcd(numerator, denominator);
const divisor = gcd(numerator, denominator);
return [numerator / num, denominator / num];
return { numerator: numerator / divisor, denominator: denominator / divisor };

@@ -72,20 +59,20 @@ }

*
* @param {number} a The first number.
* @param {number} b The second number.
* @param {number} num1 The first number.
* @param {number} num2 The second number.
*
* @returns {number} The GCD between the two numbers.
* @returns {number} Returns the greatest common divisor between the two numbers.
*/
function gcd(a, b) {
function gcd(num1, num2) {
while (b !== 0) {
while (num2 !== 0) {
let temp = a;
let temp = num1;
a = b;
num1 = num2;
b = temp % b;
num2 = temp % num2;
}
return a;
return num1;

@@ -95,263 +82,377 @@ }

/**
* Curtail is a pure JavaScript in browser canvas-based image manipulation tool.
* Crop an image to a specified size by providing the start location of the crop and
* the dimensions that the product should have.
*
* @since 0.1.0
*
* @param {string} path The path to the image to crop.
* @param {number} x The horizontal location in the original image to begin the crop.
* @param {number} y The vertical location in the original image to being the crop.
* @param {number} width The width of the final cropped image.
* @param {number} height The height of of the final cropped image.
* @param {Object} [options]
* @param {boolean} [options.autoDownload=false] Indicates whether the image should download after the cropping is complete or not.
* @param {string} [options.crossOrigin=null] Sets the cross-origin property of images originating from external sources.
*
* @returns {Promize<HTMLImageElement>} Returns the newly cropped image as an image element.
*/
export class Curtail {
export function crop(path, x, y, width, height, options = {}) {
/**
* @param {Object} [options] Options used to alter the functionality of Curtail.
* @param {boolean} [autoDownload=false] Indicates whether the new image will be queued to download automatically after it is transformed.
* @param {string} [crossOrigin=null] Set a cross-origin property for images loaded from non-local sources.
*/
constructor(options = {}) {
const _options = Object.assign({
/**
* Combine the user options with the defaults for any options not set.
*
* @prop {Object}
* @readonly
*/
this._options = Object.assign({
autoDownload: false,
/**
* Indicates whether the image should auto-download after the edit.
*
* @prop {boolean}
*/
autoDownload: false,
crossOrigin: null
/**
* Sets a cross-origin property for the images used.
*
* @prop {string}
*/
crossOrigin: null
}, options);
}, options);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
/**
* Used when converting an image to another format, it has to be from the
* following supported formats.
*
* @prop {Object}
*/
this.FORMAT = {
const fileInfo = utils.extractFileInfo(path);
PNG: { ext: 'png', transparent: true },
const originalImage = new Image();
JPG: { ext: 'jpg', transparent: false },
return new Promise((resolve, reject) => {
GIF: { ext: 'gif', transparent: false },
originalImage.addEventListener('load', function loadImage() {
BMP: { ext: 'bmp', transparent: false },
canvas.width = width;
canvas.height = height;
WEBP: { ext: 'webp', transparent: true },
ctx.drawImage(originalImage, x, y, width, height, 0, 0, width, height);
PDF: { ext: 'pdf', transparent: true },
const croppedImage = new Image();
};
croppedImage.addEventListener('load', function loadCroppedImage() {
}
if (_options.autoDownload) {
/**
* Crop an image down to a specified size by providing the location to being cropping
* the image and the dimensions of the new desired image.
*
* @since 0.1.0
*
* @param {string} src The path to the image to crop.
* @param {number} x The x location in the original image to begin the crop.
* @param {number} y The y location in the original image to begin the crop.
* @param {number} width The desired width for the cropped image.
* @param {number} height The desired height for the cropped image.
*
* @returns {Promise<HTMLImageElement>} The newly cropped image.
*/
crop(src, x, y, width, height) {
const imageLink = document.createElement('a');
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
imageLink.href = croppedImage.src;
imageLink.download = fileInfo.name + '.' + fileInfo.ext;
const nameIndex = src.lastIndexOf('/') + 1 || 0;
const extIndex = src.lastIndexOf('.');
imageLink.click();
const srcName = src.slice(nameIndex, extIndex);
const srcExt = src.slice(extIndex + 1);
}
const originalImage = new Image();
croppedImage.removeEventListener('load', loadCroppedImage);
return new Promise((resolve, reject) => {
resolve(croppedImage);
originalImage.onload = () => {
});
canvas.width = width;
canvas.height = height;
croppedImage.addEventListener('error', function loadCroppedImageError(err) {
ctx.drawImage(originalImage, x, y, width, height, 0, 0, width, height);
croppedImage.removeEventListener('error', loadCroppedImage);
const croppedImage = new Image();
reject(err);
croppedImage.onload = () => {
});
if (this._options.autoDownload) {
croppedImage.src = canvas.toDataURL(`image/${fileInfo.ext}`).replace(`image/${fileInfo.ext}`, 'image/octet-stream');
let img = document.createElement('a');
});
img.href = croppedImage.src;
img.download = srcName + '.' + srcExt;
originalImage.addEventListener('error', function loadImageError(err) {
img.click();
originalImage.removeEventListener('error', loadImageError);
}
reject(err);
resolve(croppedImage);
});
originalImage.src = path;
if (_options.crossOrigin) originalImage.crossOrigin = _options.crossOrigin;
});
}
/**
* Convert an image from one format to another format.
*
* @since 1.0.0
*
* @param {string} path The path to the image to convert to another format.
* @param {string} format The new format for the image.
* @param {Object} [options]
* @param {boolean} [options.autoDownload=false] Indicates whether the image should download after the cropping is complete or not.
* @param {string} [options.crossOrigin=null] Sets the cross-origin property of images originating from external sources.
*
* @returns {Promise<HTMLImageElement>} Returns the newly formatted image as an image element.
*/
export function convert(path, format, options = {}) {
const _options = Object.assign({
autoDownload: false,
crossOrigin: null
}, options);
const nonTransparentFormats = ['jpg', 'jpeg', 'gif', 'bmp'];
const fileInfo = utils.extractFileInfo(path);
if (fileInfo.ext === format) return;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const originalImage = new Image();
return new Promise((resolve, reject) => {
originalImage.addEventListener('load', function loadImage() {
canvas.width = originalImage.width;
canvas.height = originalImage.height;
if (nonTransparentFormats.includes(format)) {
ctx.fillStyle = '#FFF';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(originalImage, 0, 0);
const convertedImage = new Image();
convertedImage.addEventListener('load', function loadConvertedImage() {
if (_options.autoDownload) {
const imageLink = document.createElement('a');
imageLink.href = convertedImage.src;
imageLink.download = fileInfo.name + '.' + format;
imageLink.click();
}
croppedImage.onerror = (err) => reject(err);
convertedImage.removeEventListener('load', loadConvertedImage);
croppedImage.src = canvas.toDataURL(`image/${srcExt}`).replace(`image/${srcExt}`, 'image/octet-stream');
resolve(convertedImage);
};
});
originalImage.onerror = (err) => reject(err);
convertedImage.addEventListener('error', function loadConvertedImageError(err) {
originalImage.src = src;
if (this._options.crossOrigin) originalImage.crossOrigin = this._options.crossOrigin;
convertedImage.removeEventListener('load', loadConvertedImageError);
reject(err);
});
convertedImage.src = canvas.toDataURL(`image/${format}`);
originalImage.removeEventListener('load', loadImage);
});
}
originalImage.addEventListener('error', function loadImageError(err) {
/**
* Convert an image from one format to another format, eg png to jpg.
*
* @since 1.0.0
*
* @param {string} src The path to the image to convert.
* @param {FORMAT} format The format, from the `curtail.FORMAT` object to convert the image to.
*
* @returns {Promise<HTMLImageElement>} The newly converted image.
*/
convert(src, format) {
originalImage.removeEventListener('load', loadImageError);
const fileInfo = extract.getFileInfo(src);
reject(err);
if (fileInfo.ext === format.ext) {
});
console.warn('Image is already in desired format.');
return;
originalImage.src = path;
}
if (_options.crossOrigin) originalImage.crossOrigin = _options.crossOrigin;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
});
const originalImage = new Image();
}
return new Promise((resolve, reject) => {
/**
* Resize an image to a new dimension.
*
* @since 1.0.0
*
* @param {string} path The path to the image to resize.
* @param {string} dimension Which dimension to resize, either width or height. Keep in mind that if you're preserving the aspect ratio, the other will resize accordingly.
* @param {number} size The new size to make the specified dimension.
* @param {Object} [options]
* @param {boolean} [options.preserveAspectRatio=true] Indicates whether the width and height will resize together to preserve the aspect ratio of the image.
* @param {boolean} [options.autoDownload=false] Indicates whether the image should download after the cropping is complete or not.
* @param {string} [options.crossOrigin=null] Sets the cross-origin property of images originating from external sources.
*
* @returns {Promise<HTMLImageElement>} Returns the newly resized image as an image element.
*/
export function resize(path, dimension, size, options = {}) {
originalImage.onload = () => {
const _options = Object.assign({
canvas.width = originalImage.width;
canvas.height = originalImage.height;
preserveAspectRatio: true,
if (!format.transparent) {
autoDownload: false,
ctx.fillStyle = '#FFF';
ctx.fillRect(0, 0, canvas.width, canvas.height);
crossOrigin: null
}
}, options);
ctx.drawImage(originalImage, 0, 0);
const originalImage = new Image();
const newImage = new Image();
return new Promise((resolve, reject) => {
newImage.onload = () => {
originalImage.addEventListener('load', function loadImage() {
if (this._options.autoDownload) {
const aspectRatio = utils.simplify(originalImage.width, originalImage.height);
let img = document.createElement('a');
if (dimension === 'width') {
img.href = newImage.src;
img.download = fileInfo.name + '.' + format.ext;
originalImage.width = size;
img.click();
if (_options.preserveAspectRatio) originalImage.height = Math.round((aspectRatio.denominator / aspectRatio.numerator) * size);
}
}
else if (dimension === 'height') {
resolve(newImage);
originalImage.height = size;
};
if (_options.preserveAspectRatio) originalImage.width = Math.round((aspectRatio.numerator / aspectRatio.denominator) * size);
newImage.onerror = (err) => reject(err);
}
newImage.src = canvas.toDataURL(`image/${format.ext}`);
originalImage.removeEventListener('load', loadImage);
};
if (_options.autoDownload) {
originalImage.onerror = (err) => reject(err);
const imageLink = document.createElement('a');
originalImage.src = src;
if (this._options.crossOrigin) originalImage.crossOrigin = this._options.crossOrigin;
imageLink.href = convertedImage.src;
imageLink.download = fileInfo.name + '.' + format;
imageLink.click();
}
resolve(originalImage);
});
}
originalImage.addEventListener('error', function loadImageError(err) {
/**
* Resize an image.
*
* The aspect ratio is automatically preserved when resizing an image unless
* the `preserveAspectRatio` parameter is set to false.
*
* @since 0.1.0
*
* @param {string} src The path to the image to convert.
* @param {string} dimsension Whether you want to resize the width or height of the image.
* @param {number} size The new size to make the specified dimension in pixels.
* @param {boolean} [preserveAspectRatio=true] Indicates whether the width and height should resize together to preserve the aspect ratio of the image.
*
* @returns {Promise<HTMLImageElement>} The newly resized image.
*/
resize(src, dimension, size, preserveAspectRatio = true) {
originalImage.removeEventListener('error', loadImageError);
const image = new Image();
reject(err);
return new Promise((resolve, reject) => {
});
image.onload = () => {
originalImage.src = path;
const aspectRatio = math.simplify(image.width, image.height);
if (_options.crossOrigin) originalImage.crossOrigin = _options.crossOrigin;
if (dimension === 'width') {
});
image.width = size;
}
if (preserveAspectRatio) image.height = Math.round((aspectRatio[1] / aspectRatio[0]) * size);
/**
* Adds the specified amount of padding around an image.
*
* Note that the padding will not be even on images that are not square.
*
* @since 2.0.0
*
* @param {string} path The path to the image to add padding to.
* @param {number} padding The amount of padding to add to the image.
* @param {Object} [options]
* @param {string} [options.paddingColor='transparent'] The color that the padding will be. This value can be any valid CSS color value such as white or #FFFFFF.
* @param {boolean} [options.autoDownload=false] Indicates whether the image should download after the cropping is complete or not.
* @param {string} [options.crossOrigin=null] Sets the cross-origin property of images originating from external sources.
*
* @returns {Promise<HTMLImageElement>} Returns the newly padded image as an image element.
*/
export function pad(path, padding, options = {}) {
}
const _options = Object.assign({
else if (dimension === 'height') {
paddingColor: 'transparent',
image.height = size;
autoDownload: false,
if (preserveAspectRatio) image.width = Math.round((aspectRatio[0] / aspectRatio[1]) * size);
crossOrigin: null
}, options);
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const fileInfo = utils.extractFileInfo(path);
const originalImage = new Image();
return new Promise((resolve, reject) => {
originalImage.addEventListener('load', function loadImage() {
canvas.width = originalImage.width + (padding * 2);
canvas.height = originalImage.height + (padding * 2);
if (_options.paddingColor !== 'transparent') {
ctx.fillStyle = _options.paddingColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(originalImage, canvas.width / 2 - originalImage.width / 2, canvas.height / 2 - originalImage.height / 2, originalImage.width, originalImage.height);
const paddedImage = new Image();
paddedImage.addEventListener('load', function loadPaddedImage() {
if (_options.autoDownload) {
const imageLink = document.createElement('a');
imageLink.href = paddedImage.src;
imageLink.download = fileInfo.name + '.' + format;
imageLink.click();
}
resolve(image);
paddedImage.removeEventListener('load', loadPaddedImage);
};
resolve(paddedImage);
image.onerror = (err) => reject(err);
});
image.src = src;
if (this._options.crossOrigin) image.crossOrigin = this._options.crossOrigin;
paddedImage.addEventListener('error', function loadPaddedImageError(err) {
paddedImage.removeEventListener('load', loadPaddedImageError);
reject(err);
});
paddedImage.src = canvas.toDataURL(`image/${fileInfo.ext}`);
originalImage.removeEventListener('load', loadImage);
});
}
originalImage.addEventListener('error', function loadImageError(err) {
originalImage.removeEventListener('error', loadImageError);
reject(err);
});
originalImage.src = path;
if (_options.crossOrigin) originalImage.crossOrigin = _options.crossOrigin;
});
}

@@ -1,7 +0,10 @@

function getFileInfo$$module$Input_0(a){var b=0,d={name:null,ext:null};-1<a.lastIndexOf("/")&&(b=a.lastIndexOf("/"));var e=a.lastIndexOf(".");d.name=a.slice(b+1,e);d.ext=a.slice(e+1);return d}function simplify$$module$Input_0(a,b){var d=gcd$$module$Input_0(a,b);return[a/d,b/d]}function gcd$$module$Input_0(a,b){for(;0!==b;){var d=a;a=b;b=d%b}return a}
var Curtail$$module$Input_0=function(a){a=void 0===a?{}:a;this._options=Object.assign({autoDownload:!1,crossOrigin:null},a);this.FORMAT={PNG:{ext:"png",transparent:!0},JPG:{ext:"jpg",transparent:!1},GIF:{ext:"gif",transparent:!1},BMP:{ext:"bmp",transparent:!1},WEBP:{ext:"webp",transparent:!0},PDF:{ext:"pdf",transparent:!0}}};
Curtail$$module$Input_0.prototype.crop=function(a,b,d,e,g){var c=this,f=document.createElement("canvas"),k=f.getContext("2d"),h=a.lastIndexOf("/")+1||0,l=a.lastIndexOf("."),p=a.slice(h,l),n=a.slice(l+1),m=new Image;return new Promise(function(h,l){m.onload=function(){f.width=e;f.height=g;k.drawImage(m,b,d,e,g,0,0,e,g);var a=new Image;a.onload=function(){if(c._options.autoDownload){var b=document.createElement("a");b.href=a.src;b.download=p+"."+n;b.click()}h(a)};a.onerror=function(a){return l(a)};
a.src=f.toDataURL("image/"+n).replace("image/"+n,"image/octet-stream")};m.onerror=function(a){return l(a)};m.src=a;c._options.crossOrigin&&(m.crossOrigin=c._options.crossOrigin)})};
Curtail$$module$Input_0.prototype.convert=function(a,b){var d=this,e=extract.getFileInfo(a);if(e.ext===b.ext)console.warn("Image is already in desired format.");else{var g=document.createElement("canvas"),c=g.getContext("2d"),f=new Image;return new Promise(function(k,h){f.onload=function(){g.width=f.width;g.height=f.height;b.transparent||(c.fillStyle="#FFF",c.fillRect(0,0,g.width,g.height));c.drawImage(f,0,0);var a=new Image;a.onload=function(){if(d._options.autoDownload){var c=document.createElement("a");
c.href=a.src;c.download=e.name+"."+b.ext;c.click()}k(a)};a.onerror=function(a){return h(a)};a.src=g.toDataURL("image/"+b.ext)};f.onerror=function(a){return h(a)};f.src=a;d._options.crossOrigin&&(f.crossOrigin=d._options.crossOrigin)})}};
Curtail$$module$Input_0.prototype.resize=function(a,b,d,e){var g=this;e=void 0===e?!0:e;var c=new Image;return new Promise(function(f,k){c.onload=function(){var a=math.simplify(c.width,c.height);"width"===b?(c.width=d,e&&(c.height=Math.round(a[1]/a[0]*d))):"height"===b&&(c.height=d,e&&(c.width=Math.round(a[0]/a[1]*d)));f(c)};c.onerror=function(a){return k(a)};c.src=a;g._options.crossOrigin&&(c.crossOrigin=g._options.crossOrigin)})};var module$Input_0={};module$Input_0.Curtail=Curtail$$module$Input_0;
function extractFileInfo$$module$Input_0(a){var e=0,b={name:null,ext:null};-1<a.lastIndexOf("/")&&(e=a.lastIndexOf("/"));var f=a.lastIndexOf(".");b.name=a.slice(e+1,f);b.ext=a.slice(f+1);return b}function simplify$$module$Input_0(a,e){var b=gcd$$module$Input_0(a,e);return{numerator:a/b,denominator:e/b}}function gcd$$module$Input_0(a,e){for(;0!==e;){var b=a;a=e;e=b%e}return a}
function crop$$module$Input_0(a,e,b,f,g,d){d=void 0===d?{}:d;var h=Object.assign({autoDownload:!1,crossOrigin:null},d),c=document.createElement("canvas"),k=c.getContext("2d"),l=utils.extractFileInfo(a),m=new Image;return new Promise(function(d,p){m.addEventListener("load",function(){c.width=f;c.height=g;k.drawImage(m,e,b,f,g,0,0,f,g);var a=new Image;a.addEventListener("load",function n(){if(h.autoDownload){var b=document.createElement("a");b.href=a.src;b.download=l.name+"."+l.ext;b.click()}a.removeEventListener("load",
n);d(a)});a.addEventListener("error",function(b){a.removeEventListener("error",loadCroppedImage);p(b)});a.src=c.toDataURL("image/"+l.ext).replace("image/"+l.ext,"image/octet-stream")});m.addEventListener("error",function n(a){m.removeEventListener("error",n);p(a)});m.src=a;h.crossOrigin&&(m.crossOrigin=h.crossOrigin)})}
function convert$$module$Input_0(a,e,b){b=void 0===b?{}:b;var f=Object.assign({autoDownload:!1,crossOrigin:null},b),g=["jpg","jpeg","gif","bmp"],d=utils.extractFileInfo(a);if(d.ext!==e){var h=document.createElement("canvas"),c=h.getContext("2d"),k=new Image;return new Promise(function(b,m){k.addEventListener("load",function p(){h.width=k.width;h.height=k.height;g.includes(e)&&(c.fillStyle="#FFF",c.fillRect(0,0,h.width,h.height));c.drawImage(k,0,0);var a=new Image;a.addEventListener("load",function n(){if(f.autoDownload){var c=
document.createElement("a");c.href=a.src;c.download=d.name+"."+e;c.click()}a.removeEventListener("load",n);b(a)});a.addEventListener("error",function v(b){a.removeEventListener("load",v);m(b)});a.src=h.toDataURL("image/"+e);k.removeEventListener("load",p)});k.addEventListener("error",function r(a){k.removeEventListener("load",r);m(a)});k.src=a;f.crossOrigin&&(k.crossOrigin=f.crossOrigin)})}}
function resize$$module$Input_0(a,e,b,f){f=void 0===f?{}:f;var g=Object.assign({preserveAspectRatio:!0,autoDownload:!1,crossOrigin:null},f),d=new Image;return new Promise(function(f,c){d.addEventListener("load",function l(){var a=utils.simplify(d.width,d.height);"width"===e?(d.width=b,g.preserveAspectRatio&&(d.height=Math.round(a.denominator/a.numerator*b))):"height"===e&&(d.height=b,g.preserveAspectRatio&&(d.width=Math.round(a.numerator/a.denominator*b)));d.removeEventListener("load",l);g.autoDownload&&
(a=document.createElement("a"),a.href=convertedImage.src,a.download=fileInfo.name+"."+format,a.click());f(d)});d.addEventListener("error",function q(a){d.removeEventListener("error",q);c(a)});d.src=a;g.crossOrigin&&(d.crossOrigin=g.crossOrigin)})}
function pad$$module$Input_0(a,e,b){b=void 0===b?{}:b;var f=Object.assign({paddingColor:"transparent",autoDownload:!1,crossOrigin:null},b),g=document.createElement("canvas"),d=g.getContext("2d"),h=utils.extractFileInfo(a),c=new Image;return new Promise(function(b,l){c.addEventListener("load",function q(){g.width=c.width+2*e;g.height=c.height+2*e;"transparent"!==f.paddingColor&&(d.fillStyle=f.paddingColor,d.fillRect(0,0,g.width,g.height));d.drawImage(c,g.width/2-c.width/2,g.height/2-c.height/2,c.width,
c.height);var a=new Image;a.addEventListener("load",function r(){if(f.autoDownload){var c=document.createElement("a");c.href=a.src;c.download=h.name+"."+format;c.click()}a.removeEventListener("load",r);b(a)});a.addEventListener("error",function u(b){a.removeEventListener("load",u);l(b)});a.src=g.toDataURL("image/"+h.ext);c.removeEventListener("load",q)});c.addEventListener("error",function t(a){c.removeEventListener("error",t);l(a)});c.src=a;f.crossOrigin&&(c.crossOrigin=f.crossOrigin)})}
var module$Input_0={};module$Input_0.extractFileInfo=extractFileInfo$$module$Input_0;module$Input_0.simplify=simplify$$module$Input_0;module$Input_0.crop=crop$$module$Input_0;module$Input_0.convert=convert$$module$Input_0;module$Input_0.resize=resize$$module$Input_0;module$Input_0.pad=pad$$module$Input_0;
{
"name": "curtail",
"version": "1.0.2",
"description": "Curtail is a pure JavaScript in browser canvas-based image manipulation tool.",
"version": "2.0.0",
"description": "Curtail is a pure JavaScript image manipulation tool.",
"main": "curtail.js",

@@ -14,3 +14,5 @@ "scripts": {

"keywords": [
"image", "crop", "format"
"image",
"crop",
"format"
],

@@ -17,0 +19,0 @@ "author": "Robert Corponoi",

<p align="center">
<img width="250" height="250" src="./Curtail.png">
<img width="250" height="250" src="./curtail.png">
</p>

@@ -7,3 +7,3 @@

<p align="center">Curtail is a pure JavaScript in browser canvas-based image manipulation tool.<p>
<p align="center">Curtail is a pure JavaScript image manipulation tool.<p>

@@ -28,9 +28,9 @@ <div align="center">

and to use it, you can import it as an ES6 module:
Curtail doesn't have a named export so to use it as an ES6 module use the following import:
```js
import { Curtail } from './node_modules/curtail/curtail.js';
import * as curtail from './node_modules/curtail/curtail.js';
```
or reference the script:
or reference the script from the dist folder:

@@ -41,27 +41,2 @@ ```html

## **Initialization**
After referencing Curtail, a new instance can be created like below:
```js
const curtail = new Curtail();
```
Curtail does accept some optional parameters on initialization as highlighted below:
| param | type | description | default |
|--------------|---------|---------------------------------------------------------------------------------|---------|
| autoDownload | boolean | If set to true, the newly edited file will automatically be queued to download. | false |
| crossOrigin | string | Cross-origin property to set if the images are from a non-local source. | null |
So let's say you would like your images to be downloaded after edits, you would initialize Curtail like:
```js
const options = {
autoDownload: true
};
const curtail = new Curtail(options);
```
## **API**

@@ -73,12 +48,14 @@

Curtail's crop method lets you input an image, crop location, and crop dimensions and returns a newly cropped version
of the original image.
The crop method takes the path to an image, a crop start location, and the final dimensons of the image and returns the newly cropped version of the original image.
| param | type | description | default |
|--------|--------|-------------------------------------------------|---------|
| src | string | The path to the image. | |
| x | number | Where to begin cropping the image horizontally. | |
| y | number | Where to begin cropping the image vertically. | |
| width | number | The width of the new image. | |
| height | number | The height of the new image. | |
| param | type | description | default |
|----------------------|---------|------------------------------------------------------------------------------------|---------|
| path | string | The path to the image to crop | |
| x | number | The horizontal starting location of the crop | |
| y | number | The vertical starting location of the crop | |
| width | number | The width of the cropped image | |
| height | number | The height of the cropped image | |
| options | Object | | {} |
| options.autoDownload | boolean | Indicates whether the image should download after the cropping is complete or not. | false |
| options.crossOrigin | string | Sets the cross-origin property of images originating from external sources. | null |

@@ -119,12 +96,13 @@ Using `Promise.then`:

Curtail's convert method takes an image and converts it from one image format to another.
The convert method takes an image and converts it from one image format to another.
Note that in order to normalize format input, the `format` parameter will have to be selected from the `curtail.FORMAT` object.
If you have a transparent image and convert it to a format that doesn't support transparency, the image will be placed on a white background.
| param | type | description | default |
|--------|----------------|-------------------------------------------------|---------|
| src | string | The path to the image. | |
| format | Curtail.FORMAT | Where to begin cropping the image horizontally. | |
| param | type | description | default |
|----------------------|---------|------------------------------------------------------------------------------------|---------|
| path | string | The path to the image to crop | |
| format | string | The new format for the image | |
| options | Object | | {} |
| options.autoDownload | boolean | Indicates whether the image should download after the cropping is complete or not. | false |
| options.crossOrigin | string | Sets the cross-origin property of images originating from external sources. | null |

@@ -136,3 +114,3 @@ Using `Promise.then`:

// with a width of 720x480.
curtail.convert('./path/to/image.png', curtail.FORMAT.JPG).then((newImage) => {
curtail.convert('./path/to/image.png', 'jpg').then((newImage) => {

@@ -154,3 +132,3 @@ // newImage will be your newly converted image and if autoDownload is set to true

// You should probably use `try, catch`
const newImage = curtail.convert('./path/to/image.png', curtail.FORMAT.JPG).catch((err) => console.log(err));
const newImage = curtail.convert('./path/to/image.png', 'jpg').catch((err) => console.log(err));

@@ -167,10 +145,13 @@ // newImage will be your newly converted image and if autoDownload is set to true

Curtail's resize method takes an image and resizes it, maintaining its aspect ratio by default.
The resize method takes an image and resizes it, maintaining its aspect ratio by default.
| param | type | description | default |
|---------------------|---------|----------------------------------------------------------------------------------------------------------|---------|
| src | string | The path to the image | |
| dimension | string | The side you want to resize, width or height. | |
| size | number | The new size of the side to resize, in pixels. | |
| preserveAspectRatio | boolean | Indicates whether the width and height should resize together to preserve the aspect ratio of the image. | true |
| param | type | description | default |
|-----------------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------|---------|
| path | string | The path to the image to crop | |
| format | string | Which dimension to resize, either width or height. Keep in mind that if you're preserving the aspect ratio, the other will resize accordingly | |
| size | number | The new size to make the specified dimension | |
| options | Object | | {} |
| options.preserveAspectRatio | boolean | Indicates whether the width and height will resize together to preserve the aspect ratio of the image | true |
| options.autoDownload | boolean | Indicates whether the image should download after the cropping is complete or not. | false |
| options.crossOrigin | string | Sets the cross-origin property of images originating from external sources. | null |

@@ -209,4 +190,47 @@ Using `Promise.then`:

### **pad**
The pad method takes an image and adds the specified amount of padding to it.
| param | type | description | default |
|----------------------|---------|----------------------------------------------------------------------------------------------------------|---------------|
| path | string | The path to the image to crop | |
| padding | number | The amount of padding to add to the image | |
| options | Object | | {} |
| options.paddingColor | string | The color that the padding will be. This value can be any valid CSS color value such as white or #FFFFFF | 'transparent' |
| options.autoDownload | boolean | Indicates whether the image should download after the cropping is complete or not. | false |
| options.crossOrigin | string | Sets the cross-origin property of images originating from external sources. | null |
Using `Promise.then`:
```js
// This will take an image and add 20px of blue padding to all sides.
curtail.pad('./path/to/image.png', 20, { paddingColor: 'blue' }).then((newImage) => {
// newImage will be your newly padded image and if autoDownload is set to true
// then you will have a local copy downloaded at this time.
});
```
Using `async/await`:
```js
async function main() {
// This will take an image and add 20px of blue padding to all sides.
// You should probably use `try, catch`
const newImage = curtail.pad('./path/to/image.png', 20, { paddingColor: 'blue' }).catch((err) => console.log(err));
// newImage will be your newly padded image and if autoDownload is set to true
// then you will have a local copy downloaded at this time.
}
main();
```
## **License**
MIT
'use strict'
import { Curtail } from '../curtail.js';
import * as extract from '../extract.js';
import * as curtail from '../curtail.js';
// Test the fucionality of Curtail's image manipulation features.
describe('Curtail', () => {
describe('Cropping an image', () => {
// Test the crop function which resizes images.
describe('#crop()', () => {
it('should crop an image starting at (200, 300) and end up with a new dimension of 450x540', async () => {
// The specified image should be cropped at the origin but with a new dimension of 300x400.
it('should crop an image at (0, 0) and result in a new dimension of 300x400', async () => {
try {
const curtail = new Curtail();
const crop = await curtail.crop('../test/wallpaper.png', 200, 300, 450, 540);
const crop = await curtail.crop('../test/wallpaper.png', 0, 0, 300, 400).catch((err) => console.log(err));
chai.expect({ width: crop.width, height: crop.height }).to.deep.equal({ width: 450, height: 540 });
const cropDimensions = { width: crop.width, height: crop.height };
}
catch (err) {
chai.expect(cropDimensions).to.deep.equal({ width: 300, height: 400 });
throw new Error(err);
}
});
});
});
describe('Changing the format of an image', () => {
it('should convert an image from png to jpg', async () => {
try {
const convert = await curtail.convert('../test/skeleton.png', 'jpg');
}
catch (err) {
throw new Error(err);
}
});
// Test the convert function which converts images between file types.
describe('#convert()', () => {
});
// The specified image should be changed from wallpaper.png to wallpaper.jpg.
it('should convert the image from .png to .jpg', async () => {
describe('Resizing an image', () => {
const curtail = new Curtail();
it('should resize the width of an image keeping the aspect ratio', async () => {
const convert = await curtail.convert('../test/wallpaper.png', curtail.FORMAT.JPG);
try {
});
const resize = await curtail.resize('../test/1920x1080.png', 'width', 400);
chai.expect({ width: resize.width, height: resize.height }).to.deep.equal({ width: 400, height: 225 });
}
catch (err) {
throw new Error(err);
}
});
// Test the resize function which resizes images.
describe('#resize()', () => {
it('should resize the height of an image keeping the aspect ratio', async () => {
// It sould resize the image's width and maintain the aspect ratio
it('it should resize the image\'s width maintaining the aspect ratio resulting in the image being 400x225', async () => {
try {
const curtail = new Curtail();
const resize = await curtail.resize('../test/1920x1080.png', 'height', 225);
const resize = await curtail.resize('../test/1920x1080.png', 'width', 400).catch((err) => console.log(err));
chai.expect({ width: resize.width, height: resize.height }).to.deep.equal({ width: 400, height: 225 });
const expectedSize = { width: 400, height: 225 };
}
catch (err) {
const actualSize = { width: resize.width, height: resize.height };
throw new Error(err);
}
chai.expect(actualSize).to.deep.equal(expectedSize);
});
});
it('should resize the width of an image not keeping the aspect ratio', async () => {
// It sould resize the image's height and maintain the aspect ratio
it('it should resize the image\'s height maintaining the aspect ratio resulting in the image being 400x225', async () => {
try {
const curtail = new Curtail();
const resize = await curtail.resize('../test/1920x1080.png', 'width', 400, { preserveAspectRatio: false });
const resize = await curtail.resize('../test/1920x1080.png', 'height', 225).catch((err) => console.log(err));
chai.expect({ width: resize.width, height: resize.height }).to.deep.equal({ width: 400, height: 1080 });
const expectedSize = { width: 400, height: 225 };
}
catch (err) {
const actualSize = { width: resize.width, height: resize.height };
throw new Error(err);
}
chai.expect(actualSize).to.deep.equal(expectedSize);
});
});
it('should resize the height of an image not keeping the aspect ratio', async () => {
try {
const resize = await curtail.resize('../test/1920x1080.png', 'height', 400, { preserveAspectRatio: false });
chai.expect({ width: resize.width, height: resize.height }).to.deep.equal({ width: 1920, height: 400 });
}
catch (err) {
throw new Error(err);
}
});
});
describe('Padding an image', () => {
it('should add 20px padding around the image', async () => {
try {
const resize = await curtail.pad('../test/1920x1080.png', 20, { paddingColor: 'white ' });
chai.expect({ width: resize.width, height: resize.height }).to.deep.equal({ width: 1960, height: 1120 });
}
catch (err) {
throw new Error(err);
}
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc