You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.9 KiB
JavaScript

"use strict";
const Promise = require("bluebird");
const asExpression = require("as-expression");
const unreachable = require("@joepie91/unreachable")("@modular-matrix/client"); // FIXME when packaging
const getImageDimensions = require("../get-image-dimensions");
const getVideoDimensions = require("../get-video-dimensions");
const calculateThumbnailSize = require("../calculate-thumbnail-size");
const canvasToBlob = require("../canvas-to-blob");
const { validateOptions } = require("@validatem/core");
const required = require("@validatem/required");
const isInteger = require("@validatem/is-integer");
const oneOf = require("@validatem/one-of");
module.exports = function elementToThumbnail(_options) {
// TODO: Add a 'crop' method in the future?
let { element, maximumWidth, maximumHeight, mimetype } = validateOptions(arguments, {
element: [ required ], // FIXME: Element type validation
maximumWidth: [ required, isInteger ], // FIXME: Positive integer
maximumHeight: [ required, isInteger ], // FIXME: Positive integer
mimetype: [ required, oneOf([ "image/png", "image/jpeg" ]) ]
});
let dimensions = asExpression(() => {
if (element instanceof HTMLImageElement) {
return getImageDimensions(element);
} else if (element instanceof HTMLVideoElement) {
return getVideoDimensions(element);
} else {
unreachable("Unrecognized element type");
}
});
let { width, height } = calculateThumbnailSize({
sourceWidth: dimensions.width,
sourceHeight: dimensions.height,
targetWidth: maximumWidth,
targetHeight: maximumHeight
});
let canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
canvas.getContext("2d").drawImage(element, 0, 0, width, height);
return Promise.try(() => {
return canvasToBlob(canvas, mimetype);
}).then((blob) => {
return {
width: width,
height: height,
blob: blob
};
});
};