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
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
|
|
};
|
|
});
|
|
};
|