<div class="showcase">
  <div class="circle"></div>
  <div class="configure">
    <pre>
    <code class="javascript">
const circle = new DirectionAwareShadow({
  target: '.circle',
  blur: 30,
  spread: 0,
  offset: .8,
  color: 'rgba(79, 1, 119, 0.46)',
  inset: false,
  reverse: false
});

circle.init();
   </code>
  </pre>
  </div>
</div>
@import url('https://fonts.googleapis.com/css?family=Space+Mono:400,700&display=swap');* {
  box-sizing: border-box;
}

* {
  box-sizing: border-box;
}

body {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-image: linear-gradient( 90.7deg,  rgba(255,253,218,1) 1.9%, rgba(246,210,255,1) 39.3%, rgba(152,222,254,1) 64.7%, rgba(251,255,210,1) 100.8% );
}

.circle {
  width: 120px;
  flex-shrink: 0;
  margin-right: 50px;
  height: 120px;
  background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
  border-radius: 20px;
  box-shadow: rgba(79, 1, 119, 0.36) 1.2px 22px 30px 0px;
  position: relative;
}

.circle:before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg fill='%23fff' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 502.019 502.019'%3e%3cpath d='M444.501 210.539l-17.676-40.206a88.404 88.404 0 00-3.385-6.878c-7.161-13.093-18.911-22.95-33.088-27.756a59.824 59.824 0 00-43.146 1.801l-8.412 3.658-15.823-35.992c-5.29-12.033-14.965-21.264-27.242-25.992-12.219-4.706-25.509-4.363-37.435.963l-23.937 10.37c-4.167-6.298-9.306-11.049-15.351-14.177-11.874-6.145-26.241-5.589-42.706 1.65l-17.777 7.815-21.639-49.223c-8.288-18.853-23.643-31.785-42.127-35.48-17.351-3.467-35.005 1.43-47.234 13.101-18.429 17.587-23.724 43.993-13.5 67.251l80.667 184.65c-24.236-5.899-52.415-1.223-68.77 13.384-.664.417-1.288.919-1.857 1.504-10.81 11.134-16.141 24.582-15.416 38.889.911 18.004 11.266 35.818 29.943 51.516.082.069.165.137.249.203l162.998 128.287a9.999 9.999 0 0010.209 1.296l233.508-102.652a9.998 9.998 0 005.956-8.531l1.271-20.347c3.39-54.289-6.388-109.307-28.28-159.104zm8.319 157.858l-.891 14.267-222.438 97.785L71.339 355.976c-14.24-12.003-22.096-24.836-22.718-37.116-.407-8.047 2.353-15.514 8.208-22.226.381-.293.745-.616 1.09-.971 14.6-15.038 50.97-16.116 69.865-2.182l40.575 38.97a9.966 9.966 0 006.926 2.788 9.97 9.97 0 007.213-3.073c3.826-3.983 3.698-10.313-.285-14.139l-39.644-38.076L52.342 73.416c-8.261-18.79-.772-35.438 8.989-44.755 7.402-7.066 18.705-10.114 29.506-7.957 12.177 2.434 22.027 10.928 27.738 23.917l68.24 155.229a10 10 0 0013.179 5.13c5.056-2.223 7.353-8.123 5.13-13.179l-38.553-87.698 17.777-7.815c10.657-4.686 19.225-5.425 25.465-2.196 4.429 2.292 8.123 6.749 10.979 13.245l.001.002 40.244 91.546a10 10 0 009.159 5.978 9.962 9.962 0 004.02-.848c5.056-2.223 7.353-8.123 5.13-13.179l-36.198-82.342 23.15-10.029.115-.051c7.039-3.156 14.897-3.361 22.127-.577 7.267 2.799 12.992 8.26 16.121 15.377l47.828 108.795a10 10 0 009.159 5.978 9.962 9.962 0 004.02-.848c5.056-2.223 7.353-8.123 5.13-13.179l-23.956-54.492 8.339-3.627c19.022-8.271 40.822-.872 50.714 17.214a68.83 68.83 0 012.621 5.326l17.676 40.207c20.612 46.888 29.819 98.691 26.628 149.809z'/%3e%3cpath d='M405.593 366.776l-11.595 5.085c-5.058 2.218-7.36 8.116-5.142 13.174a10.002 10.002 0 009.163 5.986 9.967 9.967 0 004.012-.845l11.595-5.085c5.058-2.218 7.36-8.116 5.142-13.174-2.22-5.059-8.119-7.358-13.175-5.141zM358.824 387.551l-123.826 54.31c-5.058 2.218-7.36 8.116-5.142 13.174a10.002 10.002 0 009.163 5.986 9.967 9.967 0 004.012-.845l123.826-54.31c5.058-2.218 7.36-8.116 5.142-13.174-2.22-5.058-8.12-7.359-13.175-5.141z'/%3e%3c/svg%3e");
  background-size: 46px;
  background-repeat: no-repeat;
  background-position: center;
}

.showcase {
  max-width: 640px;
  margin: auto;
  display: flex;
  width: 100%;
  padding: 30px;
  align-items: center;
  flex-wrap: wrap;
  border-radius: 20px;
}

.hljs {
  font-family: 'Space Mono', monospace;
  font-size: 14px;
  padding: 0 26px;
  border-radius: 18px;
  flex: 1;
  overflow: auto;
  line-height: 1.6;
}

pre {
  margin: 0;
  display: flex;
}

.configure {
  flex: 1;
  overflow: hidden;
}

View Compiled
class DirectionAwareShadow {
  constructor({
    target = null,
    blur = 0,
    spread = 0,
    inset = false,
    reverse = false,
    color = 'currentColor',
    offset = 1
  } = {}) {
    this.target = target ? document.querySelectorAll(target) : target;
    this.blur = blur;
    this.inset = inset;
    this.spread = spread;
    this.reverse = reverse;
    this.color = color;
    this.offset = offset;
  }

  move() {
    this.target.forEach(t =>
      t.addEventListener('mousemove', e => this.calc(e))
    );
  }

  px(val) {
    return `${val}px`;
  }

  calc(e) {
    const { currentTarget, offsetX, offsetY } = e;
    const { offsetHeight, offsetWidth } = currentTarget;
    const { color, reverse, offset } = this;
    
    const blur = this.px(this.blur);
    const spread = this.px(this.spread);
    const inset = this.inset ? 'inset' : '';
  
    const x = ((offsetWidth / 2 - offsetX) * offset) / 2;
    const y = ((offsetHeight / 2 - offsetY) * offset) / 2;
 
    const h = this.px(!reverse ? x : x * -1);
    const v = this.px(!reverse ? y : y * -1);

    currentTarget.style.boxShadow = `${h} ${v} ${blur} ${spread} ${color} ${inset}`;
  }

  init() {
    if (!this.target) {
      console.error('[direction-aware shadow] • you should add a target')
      return;
    }

    this.move();
  }
}

const circle = new DirectionAwareShadow({
  target: '.circle',
  blur: 30,
  spread: 0,
  offset: .8,
  color: 'rgba(79, 1, 119, 0.36)',
  inset: false,
  reverse: false
});

circle.init();

// highlightjs
hljs.initHighlightingOnLoad();
View Compiled

External CSS

  1. https://highlightjs.org/static/demo/styles/night-owl.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js