<section class="section">
  <div class="background-hidden-container">
    <img class="background-image-hidden" src="https://images.unsplash.com/photo-1514888286974-6c03e2ca1dba?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&amp;ixlib=rb-1.2.1&amp;auto=format&amp;fit=crop&amp;w=727&amp;q=80" alt="">
  </div>

  <canvas class="background-canvas"></canvas>
  
  <div class="content">Lorem ipsum dolor sit amet consectetur adipisicing elit. Ea, rerum? Tempora hic similique laboriosam veniam sint quia dolorum perferendis cumque numquam molestiae doloribus, neque omnis id aut temporibus ducimus suscipit!</div>
</section>
body {
  margin: 0;
  display: flex;
  flex-direction: column;
  font-family: sans-serif;
}

.section {
  position: relative;
}

.background-hidden-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  visibility: hidden;
}

.background-canvas {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
}

.content {
  width: 25%;
  margin: 50px auto;
  padding: 15px;
  box-shadow: 0 0 25px #000;
  color: #fff;
  line-height: 1.35;
}
const section = document.querySelector('.section');
const content = document.querySelector('.content');
const background = document.querySelector('.background-image-hidden');
const canvas = document.querySelector('.background-canvas');
const ctx = canvas.getContext('2d');

RainyDay.prototype._animateDrops = RainyDay.prototype.animateDrops;
RainyDay.prototype.animateDrops = function () {
  this._animateDrops();
  this.afterUpdate();
};
RainyDay.prototype.afterUpdate = function () {
  const { clientWidth: bgw, clientHeight: bgh } = section;
  const { width: cw, height: ch } = this.canvas;
  canvas.width = bgw;
  canvas.height = bgh;
  
  const sizeScale = Math.max(bgw / cw, bgh / ch);
  const dw = cw * sizeScale;
  const dh = ch * sizeScale;
  const dx = (bgw - dw) * 0.5;
  const dy = (bgh - dh) * 0.5;
  ctx.drawImage(this.canvas, 0, 0, cw, ch, dx, dy, dw, dh);
  
  // clip
  ctx.save();
  ctx.rect(
    content.offsetLeft, content.offsetTop,
    content.clientWidth, content.clientHeight
  );
  ctx.clip();  
  ctx.drawImage(this.img, 0, 0, cw, ch, dx, dy, dw, dh);
  ctx.restore();
};

const rainyDay = new RainyDay({
  image: background,
  parentElement: background.parentNode,
  fps: 24,
  enableSizeChange: false,
  blur: 0
});
rainyDay.rain([[5, 2, 2]], 0);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/rainyday.js/0.1.2/rainyday.min.js