Tweakers forum question

https://gathering.tweakers.net/forum/list_messages/1788927

by jurgle

HTML

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<div class="container">
  <div class="background"></div>
  <div class="mask">
    <canvas style="position: absolute;"></canvas>
  </div>
</div>

CSS

.container {
  width: 300px;
  height: 300px;
  position: relative;
}

.container > div {
  width: 100%;
  height: 100%;
  position: absolute;
}

.background {
  background-color: #f00;
}

JavaScript

/// 
// parameters:
//   relativeX from 0 (left) to 1 (right) 
//   relativeY from 0 (top) to 1 (bottom)
// return value:
//   amount of light from 0 (black) to 1 (white)
///
function getGreyValueAt(relativeX, relativeY) {
  return (relativeX / (relativeX + relativeY * (1 - relativeX)));
}

/// 
// parameters:
//   relativeX from 0 (left) to 1 (right) 
//   relativeY from 0 (top) to 1 (bottom)
// return value:
//   alpha from 0 (transparant) to 1 (opague)
///
function getAlphaAt(relativeX, relativeY) {
  return relativeX + relativeY * (1 - relativeX)
}

(function() {
  var container = $('.container');
  var canvas = $('canvas');
  var w = container.width();
  var h = container.height();
  canvas.prop('width', w);
  canvas.prop('height', h);

  var context = canvas[0].getContext('2d');
  imageData = context.createImageData(w, h);
  pixels = imageData.data;

  pixelIndex = 0;
  for (var x = 0; x < w; x++) {
    for (var y = 0; y < h; y++) {
      var relativeX = (x + .5) / w;
      var relativeY = (y + .5) / h;

      var greyValue = getGreyValueAt(relativeX, relativeY) * 255;
      var alpha = getAlphaAt(relativeX, relativeY) * 255;

      pixelIndex = ((x * w) + y) * 4;
      pixels[pixelIndex] = greyValue;
      pixels[pixelIndex + 1] = greyValue;
      pixels[pixelIndex + 2] = greyValue;
      pixels[pixelIndex + 3] = alpha;
    }
  }
  context.putImageData(imageData, 0, 0);
})()