UNPKG

pixeli

Version:

A lightweight command-line tool for merging multiple images into customizable grid layouts.

192 lines (163 loc) 6.29 kB
import { displayWarningMessage, isSupportedOutputImage, isValidHexadecimal, parseAspectRatio, SUPPORTED_OUTPUT_FORMATS, } from './utils.js'; export const validateSharedOptions = (sharedOptions) => { // Extract params const { files, dir, recursive, shuffle, gap, canvasColor, output } = sharedOptions; // Conduct validations if ((!files || !files.length) && !dir) { throw new Error('You must specify either [files...] or --dir.'); } if (isNaN(gap) || !Number.isInteger(Number(gap)) || gap < 0) { throw new Error('--gap must be a positive integer.'); } if (canvasColor !== 'transparent' && !isValidHexadecimal(canvasColor)) { throw new Error('--canvas-color must be a valid hexadecimal value.'); } if (!isSupportedOutputImage(output)) { throw new Error('Invalid output format. Choose one of the following: ' + SUPPORTED_OUTPUT_FORMATS.join(', ')); } const formattedParams = { files: files || [], dir, recursive, shuffle, gap: Number(gap), canvasColor: canvasColor === 'transparent' ? { r: 0, g: 0, b: 0, alpha: 0 } : canvasColor, output, }; return formattedParams; }; export const validateMasonryOptions = (sharedOptions, masonryOptions) => { // Extract params const { gap } = sharedOptions; const { rowHeight, columnWidth, canvasWidth, canvasHeight, flow, hAlign, vAlign } = masonryOptions; // Define orientations and alignments for validation const FLOWS = ['horizontal', 'vertical']; const HORIZONTAL_ALIGNMENTS = ['left', 'center', 'right', 'justified']; const VERTICAL_ALIGNMENTS = ['top', 'middle', 'bottom', 'justified']; // Define orientation dependent options which are ignored if defined for the wrong orientation const IGNORED_FLOW_DEPENDENT_OPTIONS = { horizontal: [ { option: '--v-align', value: vAlign, }, { option: '--canvas-height', value: canvasHeight, }, { option: '--column-width', value: columnWidth, }, ], vertical: [ { option: '--h-align', value: hAlign, }, { option: '--canvas-width', value: canvasWidth, }, { option: '--row-height', value: rowHeight, }, ], }; // Validate orientations and alignments if (!FLOWS.includes(flow)) { throw new Error('Invalid orientation. Choose one of the following: ' + FLOWS.join(', ')); } if (hAlign && !HORIZONTAL_ALIGNMENTS.includes(hAlign)) { throw new Error('Invalid horizontal alignment. Choose one of the following: ' + HORIZONTAL_ALIGNMENTS.join(', ')); } if (vAlign && !VERTICAL_ALIGNMENTS.includes(vAlign)) { throw new Error('Invalid vertical orientation. Choose one of the following: ' + VERTICAL_ALIGNMENTS.join(', ')); } // Ensure numeric values are positive integers if (rowHeight && (isNaN(rowHeight) || !Number.isInteger(Number(rowHeight)) || Number(rowHeight) < 1)) { throw new Error('--row-height must be a positive integer.'); } if (columnWidth && (isNaN(columnWidth) || !Number.isInteger(Number(columnWidth)) || Number(columnWidth) < 1)) { throw new Error('--column-width must be a positive integer.'); } // Ensure canvas width is given if (flow === 'horizontal' && !canvasWidth) { throw new Error('--canvas-width must be given.'); } // and is a positive integer else if (flow === 'horizontal' && (isNaN(canvasWidth) || !Number.isInteger(Number(canvasWidth)) || Number(canvasWidth) < 1)) { throw new Error('--canvas-width must be a positive integer.'); } // and it accomodates for the minimum width needed else if (flow === 'horizontal' && canvasWidth <= gap * 2) { throw new Error(`--canvas-width must be greater than 2 gaps or ${gap * 2}px.`); } // Ensure canvas height is given if (flow === 'vertical' && !canvasHeight) { throw new Error('--canvas-height must be given.'); } // and is a positive integer else if (flow === 'vertical' && (isNaN(canvasHeight) || !Number.isInteger(Number(canvasHeight)) || Number(canvasHeight) < 1)) { throw new Error('--canvas-height must be a positive integer.'); } // and it accomodates for the minimum height needed else if (flow === 'vertical' && canvasHeight <= gap * 2) { throw new Error(`--canvas-height must be greater than 2 gaps or ${gap * 2}px.`); } // Validate dependent options by showing warnings when incorrect parameters // are used with incorrect orientation const ignoredFlowOptions = IGNORED_FLOW_DEPENDENT_OPTIONS[flow]; for (const { option, value } of ignoredFlowOptions) { if (value) { displayWarningMessage(`"${option}" option is ignored due to ${flow} flow.`); } } const params = { rowHeight: Number(rowHeight) || null, columnWidth: Number(columnWidth) || null, canvasHeight: Number(canvasHeight) || null, canvasWidth: Number(canvasWidth) || null, flow, hAlign, vAlign, }; return params; }; export const validateGridOptions = (sharedOptions, gridOptions) => { // Extract params const { aspectRatio, imageWidth, columns, caption, captionColor, maxCaptionSize } = gridOptions; // Ensure aspect ratio is valid const parsedAspectRatio = parseAspectRatio(aspectRatio); if (!parsedAspectRatio) { throw new Error('--aspect-ratio must be a valid ratio. Examples: 16/9, 2:3, 1x2, 1.77'); } if (imageWidth && (isNaN(imageWidth) || !Number.isInteger(Number(imageWidth)) || Number(imageWidth) < 1)) { throw new Error('--image-width must be a positive integer.'); } if (isNaN(columns) || !Number.isInteger(Number(columns)) || Number(columns) < 1) { throw new Error('--columns must be a positive integer.'); } if (isNaN(maxCaptionSize) || !Number.isInteger(Number(maxCaptionSize)) || Number(maxCaptionSize) < 2) { throw new Error('--max-caption-size must be a positive integer >= 2 (minimum caption size).'); } if (!isValidHexadecimal(captionColor)) { throw new Error('--caption-color must be a valid hexadecimal value.'); } const formattedParams = { aspectRatio: parsedAspectRatio, imageWidth: Number(imageWidth) || null, columns: Number(columns), caption, captionColor, maxCaptionSize, }; return formattedParams; };