<div id="light">
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125">
    <path d="M50 3.027a39.036 39.036 0 00-39 38.981c0 10.815 5.662 21.012 10.214 29.132 2.385 4.352 4.843 8.794 5.116 11.27v15.658a23.67 23.67 0 0047.34 0V82.41c.272-2.385 2.73-6.827 5.116-11.106C83.337 63.11 89 52.914 89 42.172A39.036 39.036 0 0050 3.027zm20.829 63.725c-3.168 5.699-5.917 10.633-6.245 14.948v16.387a14.566 14.566 0 01-29.132 0V81.7c-.327-4.315-3.077-9.25-6.245-14.948-4.242-7.647-9.103-16.387-9.103-24.78a29.896 29.896 0 0159.792 0c0 8.503-4.825 17.17-9.067 24.816z" />
    <path d="M58.458 79.965c-1.781.47-6.616.871-8.458.825-1.842.046-7.051-.543-8.833-1.012-5.788-1.842-8.556 6.843-2.767 8.685 2.665.746 8.796 1.476 11.564 1.43 2.767.046 8.523-.496 11.189-1.243 5.439-1.976 2.908-10.135-2.695-8.685z" />
    <path d="M63.169 81.373c-.539-.824-2.113-1.607-3.234-1.607-.469 0-1.485.12-2.257.266-4.93.934-11.35.786-16.65-.385-1.69-.374-2.926-.163-3.973.678l-.68.546-.225-1.141c-.56-2.846-2.271-6.646-6.098-13.54-5.479-9.87-7.745-15.258-8.617-20.488-.454-2.726-.298-7.179.35-9.945 1.254-5.358 3.637-9.792 7.335-13.643 1.03-1.072 2.505-2.43 3.277-3.017 10.397-7.899 24.389-8.003 34.856-.26 2.155 1.595 5.224 4.808 6.685 6.998 3.204 4.806 4.9 10.315 4.9 15.91 0 6.49-2.236 12.674-8.858 24.486-4.264 7.607-5.902 11.439-6.279 14.692l-.124 1.075z" fill="#ff0" />
  </svg>
</div>
<div id="object">
  <div id="shadow"></div>
</div>
:root {
  --cover-width: 200px;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  overflow-x: hidden;
}

#object {
  position: relative;
  width: var(--cover-width);
  height: calc(var(--cover-width) * 1.25);
  margin: 75px auto;
  background: linear-gradient(#e66465, #9198e5);
}

#light {
  margin-top: 50px;
  display: grid;
  justify-items: center;
  width: 100%;
  transform: translate(0);
}

#light > svg {
  width: 40px;
}

#shadow {
  content: "";
  position: absolute;
  top: 100%;
  z-index: -1;
  background-color: rgb(0, 0, 0);
  width: var(--cover-width);
  height: var(--cover-width);
  transform-origin: top center;
}
const gui = new dat.GUI({});
const light = document.getElementById("light");
const shadow = document.getElementById("shadow");

const config = {
  position: -8,
};
const weight = 5;

gui
  .add(config, "position")
  .min(-10)
  .max(10)
  .step(1)
  .name("Light Position")
  .onChange(() => {
    updatePosition();
  });

updatePosition();

function updatePosition() {
  shadow.style = `transform: skewX(${config.position * -weight}deg)`;
  light.style = `transform: translate(${getLightPosition()}vw, 0)`;
}

function getLightPosition() {
  // range is -48 to 48 so that values stay within screen
  let pos = config.position;

  if (pos < 0) {
    return pos * weight + 2;
  } else if (pos > 0) {
    return pos * weight - 2;
  }

  return 0;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js