import { supportedFormats } from '$lib/format-readers'; import { jDataView } from './jdataview'; import { Pattern } from './pattern'; /** * Render the embroidery pattern file to the provided canvas and update views. * @param {string} filename - The name of the file. * @param {ProgressEvent} evt - The file load event. * @param {HTMLCanvasElement} canvas - Canvas to render the pattern. * @param {HTMLElement} colorView - Element to display colors. * @param {HTMLElement} stitchesView - Element to display stitch count. * @param {HTMLElement} sizeView - Element to display size. * @param {{stitches: string, dimensions: string}} localizedStrings - Localized labels. */ function renderFile( filename, evt, canvas, colorView, stitchesView, sizeView, localizedStrings, ) { const fileExtension = filename.toLowerCase().split('.').pop(); const arrayBuffer = evt.target?.result; if (!(fileExtension && arrayBuffer)) { throw new Error('Invalid file extension or file data'); } const view = new jDataView(arrayBuffer, 0, evt.total || 0); const pattern = new Pattern(); const formatReader = supportedFormats[fileExtension]; if (!formatReader || typeof formatReader.read !== 'function') { throw new Error(`Unsupported file format: ${fileExtension}`); } // @ts-ignore formatReader.read(view, pattern); pattern.moveToPositive(); pattern.drawShapeTo(canvas); pattern.drawColorsTo(colorView); pattern.drawStitchesCountTo(stitchesView, localizedStrings.stitches); pattern.drawSizeValuesTo(sizeView, localizedStrings.dimensions); } /** * Display a generic abort message. * @param {HTMLElement} errorMessageRef - Element to display the message. */ function renderAbortMessage(errorMessageRef) { errorMessageRef.textContent = 'Render aborted!'; } /** * Display a detailed error message based on error type. * @param {string} errorName - The name of the error. * @param {HTMLElement} errorMessageRef - Element to display the message. */ function renderErrorMessage(errorName, errorMessageRef) { /** @type {string} */ let message; switch (errorName) { case 'NotFoundError': message = 'The file could not be found at the time the read was processed.'; break; case 'SecurityError': message = '

A file security error occurred. This can be due to:

' + ''; break; case 'NotReadableError': message = 'The file cannot be read. This can occur if the file is open in another application.'; break; case 'EncodingError': message = 'The length of the data URL for the file is too long.'; break; default: message = 'Something went wrong!'; break; } errorMessageRef.innerHTML = message; } /** * Read a file and render its pattern to canvas with error handling. * @param {File} fileObject - The file to read. * @param {HTMLCanvasElement} canvas - The canvas to render on. * @param {HTMLElement} errorMessageRef - Element to show error messages. * @param {HTMLElement} colorView - Element to display colors. * @param {HTMLElement} stitchesView - Element to display stitch count. * @param {HTMLElement} sizeView - Element to display size. * @param {{stitches: string, dimensions: string}} localizedStrings - Localized strings. * @returns {string} Empty string after starting file read. */ export default function renderFileToCanvas( fileObject, canvas, errorMessageRef, colorView, stitchesView, sizeView, localizedStrings, ) { const reader = new FileReader(); reader.onloadend = (evt) => renderFile( fileObject.name, evt, canvas, colorView, stitchesView, sizeView, localizedStrings, ); reader.onabort = () => renderAbortMessage(errorMessageRef); reader.onerror = (evt) => renderErrorMessage( // @ts-ignore evt.target.error?.name || 'UnknownError', errorMessageRef, ); if (fileObject) { reader.readAsArrayBuffer(fileObject); } return ''; }