JSFiddle - React, Tailwind, and code Playground

by brigand

HTML

<div id="first">
  <img src="" alt="" id="inner">
</div>
<div id="second"></div>

<h2>full image</h2>
<img src="" alt="" id="full">

CSS

#first, #second {
  width: 20em;
  height: 5em;
  box-shadow: 0 0 3px black;
  overflow: hidden;
  margin: 2em;
}

#inner {
  width: 100%;
}

JavaScript

function makeImage(width, height) {
const hw = Math.floor(width / 2);
const hh = Math.floor(height / 2);
	const src = `<?xml version="1.0" standalone="no"?>
  <svg viewBox="0 0 ${width} ${height}" width="${width}" height="${height}"
  version="1.1"
     xmlns="http://www.w3.org/2000/svg"
     >
  <rect width="${width}" height="${height}" fill="#999" />
<rect width="${hw}" height="${hh}" fill="hotpink" />
<rect x="${hw}" y="${hh}" width="${hw}" height="${hh}" fill="limegreen" />
  <rect x="1" y="1" width="${width - 2}" height="${height - 2}" stroke="blue" stroke-width="4" stroke-location="inside" fill="none" />
  </svg>`
  
  const url = `data:image/svg+xml;base64,${btoa(src)}`;
  return { url, width, height, aspect: width / height, crop: 0.5 }
}

function test(width, height, crop) {
  const inner = document.querySelector("img#inner");
  const full = document.querySelector("img#full");

  const { url, aspect } = makeImage(width, height);

  inner.src = url;
  full.src = url;
  inner.style.transform = `translateY(${crop * 100}%)`;

  let r_dst = 4 / 1;
  let w_dst = width;
  let h_dst = width / r_dst;
  let xform = 1 - h_dst / height;
  let c_dst = Math.abs(crop);
  let y_pos = c_dst / xform;
  let y_per = (y_pos * 100).toFixed(2);

  second.style.backgroundImage = `url("${url}")`;
  second.style.backgroundSize = "100%";
  second.style.backgroundPosition = `0 ${y_per}%`;
}


test(500, 400, -0.3);