.container
.container__content
.container__label Drag me!
.container__proximity-wrap
.container__proximity
.container__proximity-ring
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(210, 50%, 50%)
overflow hidden
.container
height 135px
width 135px
position relative
&__content
background hsl(25, 50%, 80%)
height 100%
width 100%
position absolute
border-radius 50%
z-index 2
top 50%
left 50%
transform translate(-50%, -50%)
display grid
place-items center
&__proximity
resize horizontal
min-width 200px
overflow auto
&__proximity-wrap
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
&__proximity-wrap:after
content ''
position absolute
bottom 0
right 0
height 30px
width 30px
background hsl(180, 60%, 90%)
$clip = $clip = polygon(0 100%, 100% 100%, 100% 0)
clip-path $clip
-webkit-clip-path $clip
pointer-events none
transform translate(2px, 2px)
&__proximity-wrap:before
content ''
position absolute
bottom 0
right 0
height 30px
width 30px
background hsl(180, 0%, 30%)
$clip = polygon(0 100%, 100% 100%, 100% 0)
clip-path $clip
-webkit-clip-path $clip
pointer-events none
transform translate(6px, 6px)
&__proximity-ring
border-radius 50%
aspect-ratio 1 / 1
width 100%
background hsla(0, 50%, 50%, 0.25)
// &: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'
import Draggable from 'https://cdn.skypack.dev/gsap/Draggable'
gsap.registerPlugin(Draggable)
const CONTAINER = document.querySelector('.container')
const PROXIMITY = CONTAINER.querySelector('.container__proximity')
const LABEL = CONTAINER.querySelector('.container__label')
const generateHandler = (element, cb) => ({x, y}) => {
const bounds = 100
const elementBounds = element.getBoundingClientRect()
const proximityBounds = PROXIMITY.getBoundingClientRect()
const proximity = proximityBounds.width / 2
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)
}
document.addEventListener('pointermove', generateHandler(CONTAINER, (x, y) => {
LABEL.innerText = `x: ${gsap.utils.clamp(-1, 1, x.toFixed(1))}; y: ${gsap.utils.clamp(-1, 1, y.toFixed(1))};`
}))
new Draggable(CONTAINER, {
trigger: '.container__content'
})
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.