move mouse to change light
body, html {
  background: #333;
  font-family: sans-serif;
  color: white;
}
const NUM = 10;
let win = $(window);
let mouseX = 0, mouseY = 0;
let boxes = [];

let up = function(i, max, fn) {
  fn(i++);
  if (i < max) up(i, max, fn);
};

let calcAng = function(x, y) {
  let lightPos = light.position()
  let dx = lightPos.left - x;
  let dy = lightPos.top - y;
  return -Math.atan2(dy, dx) / Math.PI  * 180;
};

let calcDist = function(x, y) {
  let lightPos = light.position()
  let dx = lightPos.left - x;
  let dy = lightPos.top - y;
  return Math.sqrt(dx * dx,  dy * dy);
};

let calcShade = function(x, y) {
  let angle = calcAng(x, y);
  let dist =  calcDist(x, y);
  let sx = dist * Math.cos(-angle * Math.PI / 180) * -1;
  let sy = dist * Math.sin(-angle * Math.PI / 180) * -1;
  
  sx = Math.min(20, Math.max(sx, -20));
  sy = Math.min(20, Math.max(sy, -20));
  let blur = Math.min(100, dist);
  let hBlur = Math.min(50, blur) * 0.5;
  // consider distance in the eq?
  return {
    bg: `-webkit-linear-gradient(${angle}deg, rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.4) ${blur}%)`,
    shadow: `${sx}px ${sy}px ${hBlur}px rgba(0, 0, 0, 0.15)`
  };
};

let randomBox = function() {
  let size =  Math.random() * 200 + 50;
  let params = { 
    size: size, 
    left: Math.random() * (win.width() - size),
    top: 50 + Math.random() * (win.height() - size)
  };
  let shade =  calcShade(params.left, params.top);
  params.bg = shade.bg;
  return box(params);
};

let box = function(p) {
  let b = $('<div>', {
    css: {
      position: 'absolute',
      left: p.left,
      top: p.top,
      width: p.size, height: p.size,
      borderRadius: 4,
      overflow: 'hidden',
      border: '1px solid rgba(255, 255, 255, 0.5)'
     }
  }).appendTo('body');
  
  let tex = $('<div>', {
    'class': 'tex',
    css: {
      position: 'absolute',
      left: 0,
      top: 0,
      width: '100%', height: '100%',
      backgroundSize: 'cover',
      background: 'url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/17496/joe.jpg)'
    }
  }).appendTo(b);
  
  let light = $('<div>', {
    'class': 'light',
    css: {
      position: 'absolute',
      left: 0,
      top: 0,
      width: '100%', height: '100%',
      
      // background: p.bg || 'gray',
      zIndex: p.zIndex || 0,
      // do this with the angle and distance somewhat
      // boxShadow: '0 20px 50px rgba(0, 0, 0, 0.2)'
    }
  }).appendTo(b);
  return b;
};

let light = box({
  size: 10,
  left: win.width() * 0.5,
  top: win.height() * 0.5,
  zIndex: 100
});

up(0, NUM, function(i) {
  boxes.push(randomBox());
});

$(document).on('mousemove', function(e) {
  mouseX = e.pageX;
  mouseY = e.pageY;
});

setInterval(function() {
  light.css({
    left: mouseX, 
    top: mouseY
  });
  
  boxes.forEach(function(item) {
    let rect = item[0].getBoundingClientRect();
    let css = calcShade(
      rect.left + rect.width / 2, 
      rect.top + rect.height / 2
    );
    item.css({
      boxShadow: css.shadow
    });
    item.find('.light').css({
      background: css.bg
    });
  });
  
}, 16);





View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js