<!DOCTYPE html>
<html>
<head>

<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.20.19/system.js"></script>
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.5.1/qs.js"></script>

<script>

SystemJS.config({
  map: {
    'plugin-babel': 'https://cdn.rawgit.com/systemjs/plugin-babel/ea37443d/plugin-babel.js',
    'systemjs-babel-build': 'https://cdn.rawgit.com/systemjs/plugin-babel/ea37443d/systemjs-babel-browser.js'
  },
  transpiler: 'plugin-babel'
});
  
(async () => {
  const layout = (await SystemJS.import('https://rawgit.com/voltrevo/84d780de0b718cd2dcb98b8c8624e7f1/raw/ec1e1f974f2ddbcd3f6a6adb29ff2dbcee6d1ab3/layout.js')).default;
  const range = n => (new Array(n)).fill(0).map((x, i) => i);
  const query = Qs.parse(location.search.slice(1));
  
  const tol = Number(query.tol || 0.2);
  
  const a = Number(query.a || (4/3));
  
  const px = (() => {
    const default_ = 640 * 480;
    
    if (!query.s) {
      return default_;
    }
    
    if (/^[0-9]+$/.test(query.s)) {
      return Number(query.s);
    }
    
    if (/^[0-9]+x[0-9]+/.test(query.s)) {
      const [w, h] = query.s.split('x').map(Number);
      return w * h;
    }
    
    console.error('Unexpected query.s: ' + query.s);
    return default_;
  })();
  
  const imgNum = Number(query.n || 7);
  
  const imgSize = () => {
    const da = Number(query.da || 1);
    const aspect = a * da ** (2 * Math.random() - 1); // From a/da to a*da
    
    const height = Math.sqrt(px / aspect);
    const width = aspect * height;
    
    return { width, height };
  };
  
  const indexes = range(imgNum);
  const rands = indexes.map(i => Math.floor(Math.random() * 1085));
  const rects = indexes.map(imgSize);
  
  const elements = layout(window.innerWidth, window.innerHeight, rects, tol);

  const blurBack = document.querySelector('#blur-back');
  
  const imgs = await Promise.all(indexes.map(i => (async () => {
    const el = elements[i];
    
    const rand = rands[i];
    const req = await fetch(`https://loremflickr.com/${Math.round(el.rect.width)}/${Math.round(el.rect.height)}?random=${Math.random()}`);
    const imgSrc = req.url;
    
    const mkImg = (dest) => {
      const img = document.createElement('img');
      img.src = imgSrc;
      img.style.width = `${dest.width}px`;
      img.style.height = `${dest.height}px`;
      img.style.left = `${dest.x}px`;
      img.style.top = `${dest.y}px`;
      
      return img;
    };
    
    return {
      backImg: mkImg(el),
      mainImg: mkImg(el.adjDest),
    };
  })()));
  
  for (const { backImg, mainImg} of imgs) {
    blurBack.appendChild(backImg);
    document.body.appendChild(mainImg);
  }
  
  window.onresize = () => {
    const els = layout(window.innerWidth, window.innerHeight, rects, tol);
    
    for (const i of indexes) {
      const { backImg, mainImg } = imgs[i];
      const el = els[i];
      
      backImg.style.width = `${el.width}px`;
      backImg.style.height = `${el.height}px`;
      backImg.style.left = `${el.x}px`;
      backImg.style.top = `${el.y}px`;
      
      mainImg.style.width = `${el.adjDest.width}px`;
      mainImg.style.height = `${el.adjDest.height}px`;
      mainImg.style.left = `${el.adjDest.x}px`;
      mainImg.style.top = `${el.adjDest.y}px`;
    }
  };
})()
.catch(err => {
  setTimeout(() => { throw err; });
});

</script>

<style>

body {
  background-color: black;
}
  
#blur-back {
  filter: blur(75px);
}
  
img {
  position: absolute;
  object-fit: cover;
  transition: all 300ms ease;
}

</style>
  
</head>
<body>
  <div id='blur-back'></div>
</body>
</html>