function draw(canvas, imageUrls) { const ctx = canvas.getContext("2d"); let promises = imageUrls.map(url => fetch(url) .then(response => response.blob()) .then(blob => createImageBitmap(blob))); Promise.all(promises).then(loadedImages => { // All images are loaded, proceed to draw ctx.clearRect(0, 0, canvas.width, canvas.height); loadedImages.forEach(image => { ctx.drawImage(image, 0, 0); }); // Get image data let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); let data = imageData.data; // Find bounding box of non-transparent area let left = canvas.width, right = 0, top = canvas.height, bottom = 0; for (let y = 0; y < canvas.height; y++) { for (let x = 0; x < canvas.width; x++) { let alpha = data[(y * canvas.width + x) * 4 + 3]; if (alpha > 0) { if (x < left) left = x; if (x > right) right = x; if (y < top) top = y; if (y > bottom) bottom = y; } } } // Calculate scaling factor let width = right - left; let height = bottom - top; let scale = Math.min(canvas.width / width, canvas.height / height); // Calculate center offsets let offsetX = (canvas.width - (width * scale)) / 2; let offsetY = (canvas.height - (height * scale)) / 2; // Clear canvas and draw scaled image ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.imageSmoothingEnabled = false; // Disable anti-aliasing loadedImages.forEach(image => { ctx.drawImage(image, left, top, width, height, offsetX, offsetY, width * scale, height * scale); }); }); }