conductor/src/instruments.js

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