.container Move your cursor!
View Compiled
*
  box-sizing border-box
  
body
  min-height 100vh
  font-weight bold
  font-size 1.15rem
  font-family sans-serif
  text-align center
  display grid
  place-items center
  background hsl(260, 50%, 50%)
  overflow hidden
  
.container
  --hue calc(180 - (var(--ratio-x, 0) * 180))
  height 135px
  width 135px
  background 'hsl(%s, 100%, 80%)' % var(--hue, 25)
  display grid
  place-content center
  border-radius 50%
  position relative
  transition transform 0.1s
  transform scale(calc(2 - var(--ratio-y, 0)))
  
  &:after
    content ''
    position absolute
    top 50%
    left 50%
    height 200px
    width 200px
    border-radius 50%
    background hsla(280, 50%, 80%, 0.5)
    transform translate(-50%, -50%)
    z-index -1
View Compiled
import gsap from 'https://cdn.skypack.dev/gsap'

const CONTAINER = document.querySelector('.container')

const generateHandler = (element, proximity, cb) => ({x, y}) => {
  const bounds = 100
  const elementBounds = element.getBoundingClientRect()
  const centerX = elementBounds.left + elementBounds.width / 2
  const centerY = elementBounds.top + elementBounds.height / 2
  const boundX = gsap.utils.mapRange(centerX - proximity, centerX + proximity, -bounds, bounds, x)
  const boundY = gsap.utils.mapRange(centerY - proximity, centerY + proximity, -bounds, bounds, y)
  cb(boundX / 100, boundY / 100)
}


const UPDATE = (x, y) => {
  const clampedX = x.toFixed(1)
  const clampedY = gsap.utils.clamp(-1, 1, y.toFixed(1))
  CONTAINER.style.setProperty('--ratio-x', clampedX)
  CONTAINER.style.setProperty('--ratio-y', clampedY)
  CONTAINER.innerText = `x: ${clampedX}; y: ${clampedY};`
}

document.addEventListener('pointermove', generateHandler(document.body, 100, UPDATE))
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.