JSFiddle - React, Tailwind, and code Playground
by RAX7
HTML
<img id="dest" alt="">
CSS
img {
display: block;
width: 400px;
height: 300px;
}
JavaScript
function loadImg(src) {
return new Promise(resolve => {
const img = new Image();
img.addEventListener('load', () => resolve(img));
img.crossOrigin = 'Anonymous';
img.src = src;
});
}
async function fillNewImage(destImage, options, offsetX = 0.5, offsetY = 0.5) {
const sourceImage = await loadImg(options.url);
const dw = destImage.clientWidth;
const dh = destImage.clientHeight;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = dw;
canvas.height = dh;
const iw = options.width;
const ih = options.height;
const ratio = Math.min(dw / iw, dh / ih);
let nw = iw * ratio;
let nh = ih * ratio;
let sx, sy, sw, sh, ar = 1;
if (nw < dw) ar = dw / nw;
if (Math.abs(ar - 1) < 1e-14 && nh < dh) ar = dh / nh;
nw *= ar;
nh *= ar;
sw = iw / (nw / dw);
sh = ih / (nh / dh);
sx = (iw - sw) * offsetX + (options.x || 0);
sx = Math.max(0, sx);
sy = (ih - sh) * offsetY + (options.y || 0);
sy = Math.max(0, sy);
ctx.drawImage(sourceImage, sx, sy, sw, sh, 0, 0, dw, dh);
let url;
function imageLoaded() {
URL.revokeObjectURL(url);
destImage.removeEventListener('load', imageLoaded);
}
destImage.addEventListener('load', imageLoaded);
canvas.toBlob(function(blob){
url = URL.createObjectURL(blob);
destImage.src = url;
});
}
const recivedData = {
x: 240,
y: 85,
width: 600,
height: 450,
url: 'https://images.unsplash.com/photo-1549288498-bbec5bc4a554?ixlib=rb-1.2.1&auto=format&fit=crop&w=1500&q=90',
};
const destImg = document.querySelector('#dest');
fillNewImage(destImg, recivedData);