141 lines
4.2 KiB
JavaScript
141 lines
4.2 KiB
JavaScript
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<FileReader>} 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 =
|
|
'<p>A file security error occurred. This can be due to:</p>' +
|
|
'<ul>' +
|
|
'<li>Accessing certain files deemed unsafe for Web applications.</li>' +
|
|
'<li>Performing too many read calls on file resources.</li>' +
|
|
'<li>The file has changed on disk since the user selected it.</li>' +
|
|
'</ul>';
|
|
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 '';
|
|
}
|