You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.0 KiB
72 lines
2.0 KiB
// Defaults
|
|
const defaultOptions = {
|
|
format: 'image/png',
|
|
quality: 0.92,
|
|
width: undefined,
|
|
height: undefined,
|
|
Canvas: undefined
|
|
};
|
|
|
|
// Return Promise
|
|
const mergeImages = (sources = [], options = {}) => new Promise(resolve => {
|
|
options = Object.assign({}, defaultOptions, options);
|
|
|
|
// Setup browser/Node.js specific variables
|
|
const canvas = options.Canvas ? new options.Canvas() : window.document.createElement('canvas');
|
|
const Image = options.Canvas ? options.Canvas.Image : window.Image;
|
|
if (options.Canvas) {
|
|
options.quality *= 100;
|
|
}
|
|
|
|
// Load sources
|
|
const images = sources.map(source => new Promise((resolve, reject) => {
|
|
// Convert sources to objects
|
|
if (source.constructor.name !== 'Object') {
|
|
source = { src: source };
|
|
}
|
|
|
|
// Resolve source and img when loaded
|
|
const img = new Image();
|
|
img.onerror = () => reject(new Error('Couldn\'t load image'));
|
|
img.onload = () => resolve(Object.assign({}, source, { img }));
|
|
img.src = source.src;
|
|
}));
|
|
|
|
// Get canvas context
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// When sources have loaded
|
|
resolve(Promise.all(images)
|
|
.then(images => {
|
|
// Set canvas dimensions
|
|
const getSize = dim => options[dim] || Math.max(...images.map(image => image.img[dim]));
|
|
canvas.width = getSize('width');
|
|
canvas.height = getSize('height');
|
|
|
|
// Draw images to canvas
|
|
images.forEach(image => {
|
|
ctx.globalAlpha = image.opacity ? image.opacity : 1;
|
|
return ctx.drawImage(image.img, image.x || 0, image.y || 0);
|
|
});
|
|
|
|
if (options.Canvas && options.format === 'image/jpeg') {
|
|
// Resolve data URI for node-canvas jpeg async
|
|
return new Promise(resolve => {
|
|
canvas.toDataURL(options.format, {
|
|
quality: options.quality,
|
|
progressive: false
|
|
}, (err, jpeg) => {
|
|
if (err) {
|
|
throw err;
|
|
}
|
|
resolve(jpeg);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Resolve all other data URIs sync
|
|
return canvas.toDataURL(options.format, options.quality);
|
|
}));
|
|
});
|
|
|
|
export default mergeImages;
|
|
|