69 lines
1.9 KiB
JavaScript
69 lines
1.9 KiB
JavaScript
async function loadInstrumentsConfig() {
|
|
const response = await fetch("/assets/instruments/instruments.json");
|
|
return await response.json();
|
|
}
|
|
|
|
async function fetchSvgText(url) {
|
|
const response = await fetch(url);
|
|
return await response.text();
|
|
}
|
|
|
|
function svgTextToImage(svgText, defaultWidth = 100, defaultHeight = 100) {
|
|
return new Promise((resolve, reject) => {
|
|
// Create a blob from the SVG text
|
|
const blob = new Blob([svgText], { type: "image/svg+xml" });
|
|
const url = URL.createObjectURL(blob);
|
|
const img = new Image();
|
|
|
|
// Set the onload callback
|
|
img.onload = () => {
|
|
// Check if naturalWidth and naturalHeight are invalid
|
|
if (img.naturalWidth === 0 || img.naturalHeight === 0) {
|
|
// Set default dimensions if image is invalid (missing width/height in SVG)
|
|
img.width = defaultWidth;
|
|
img.height = defaultHeight;
|
|
}
|
|
|
|
// Clean up the object URL to free memory
|
|
URL.revokeObjectURL(url);
|
|
|
|
resolve(img);
|
|
};
|
|
|
|
// Handle image loading errors
|
|
img.onerror = (err) => {
|
|
URL.revokeObjectURL(url); // Clean up URL
|
|
reject(err);
|
|
};
|
|
img.src = url;
|
|
});
|
|
}
|
|
|
|
export async function loadInstruments() {
|
|
const instrumentsConfig = await loadInstrumentsConfig();
|
|
const instruments = {};
|
|
|
|
for (const [instrument, config] of Object.entries(instrumentsConfig)) {
|
|
const svgText = await fetchSvgText(
|
|
`${config.directory}/${config.image.filename}`
|
|
);
|
|
|
|
// Pass the width and height to the svgTextToImage function
|
|
const img = await svgTextToImage(
|
|
svgText,
|
|
config.image.width || 100,
|
|
config.image.height || 100
|
|
);
|
|
|
|
instruments[instrument] = {
|
|
image: img,
|
|
yPos: config.image.yPos,
|
|
midiChannelName: config["midi-channel-name"],
|
|
width: config.image.width,
|
|
height: config.image.height,
|
|
};
|
|
}
|
|
|
|
return instruments;
|
|
}
|