mixin icon(key)
-
const PATH_MAP = {
Twitter: "M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z",
SitePoint: "M2.471 10.533l1.771 1.688 5.598 5.141 2.4-2.291c.21-.297.194-.705-.046-.985L9.99 12.184l.01-.005-2.371-2.266c-.279-.314-.27-.78.021-1.079l6.39-6.076L11.146 0 2.475 8.238c-.664.633-.664 1.66 0 2.295h-.004zm19.056 2.937l-1.77-1.691-5.595-5.142-2.411 2.291c-.221.3-.207.705.045.985l2.205 1.891h-.006l2.369 2.265c.27.314.27.766-.029 1.064l-6.391 6.075L12.855 24l8.67-8.238c.664-.633.666-1.659 0-2.295l.002.003z",
DevTo: "M7.42 10.05c-.18-.16-.46-.23-.84-.23H6l.02 2.44.04 2.45.56-.02c.41 0 .63-.07.83-.26.24-.24.26-.36.26-2.2 0-1.91-.02-1.96-.29-2.18zM0 4.94v14.12h24V4.94H0zM8.56 15.3c-.44.58-1.06.77-2.53.77H4.71V8.53h1.4c1.67 0 2.16.18 2.6.9.27.43.29.6.32 2.57.05 2.23-.02 2.73-.47 3.3zm5.09-5.47h-2.47v1.77h1.52v1.28l-.72.04-.75.03v1.77l1.22.03 1.2.04v1.28h-1.6c-1.53 0-1.6-.01-1.87-.3l-.3-.28v-3.16c0-3.02.01-3.18.25-3.48.23-.31.25-.31 1.88-.31h1.64v1.3zm4.68 5.45c-.17.43-.64.79-1 .79-.18 0-.45-.15-.67-.39-.32-.32-.45-.63-.82-2.08l-.9-3.39-.45-1.67h.76c.4 0 .75.02.75.05 0 .06 1.16 4.54 1.26 4.83.04.15.32-.7.73-2.3l.66-2.52.74-.04c.4-.02.73 0 .73.04 0 .14-1.67 6.38-1.8 6.68z"
}
svg.button__icon(role='img' aria-hidden="true" xmlns='http://www.w3.org/2000/svg' viewbox='0 0 24 24')
title= `${key} Icon`
path(d=PATH_MAP[key])
.scene
button.button
span.button__shadow
+icon('DevTo')
span.button__content
span.button__text SitePoint
+icon('DevTo')
span.button__shine
View Compiled
*
box-sizing border-box
transform-style preserve-3d
:root
--blur 6px
--shine-blur calc(var(--blur) * 4)
--size 25vmin
--transition 0.1s
--depth max(25px, 3vmin)
--icon-size 75%
--radius 24%
--shine hsla(0, 0%, 100%, 0.85)
--button-bg hsla(0, 0%, 0%, 0.025)
--icon-fill hsl(196, 0%, 0%)
--shadow-bg hsla(0, 0%, 0%, 0.115)
--shadow-alpha 0.4
--shadow-icon hsla(0, 0%, 0%, 0.5)
--bg hsl(196, 65%, 95%)
body
min-height 100vh
display grid
place-items center
transform-style preserve-3d
touch-action none
overflow hidden
&:before
content ''
position absolute
height 300vh
width 300vw
z-index -1
top 50%
left 50%
transform translate3d(-50%, -50%, calc(var(--size) * -1))
background var(--bg)
.scene
height var(--size)
position relative
min-height 150px
min-width 150px
width var(--size)
transform rotateX(-34deg) rotateY(22deg) rotateX(90deg)
.button
appearance none
background none
border 0
cursor pointer
height 100%
outline transparent
position absolute
width 100%
&__content
&__shadow
height 100%
width 100%
position absolute
display grid
place-items center
border-radius var(--radius)
&__content
--fill var(--icon-fill)
background var(--button-bg)
overflow hidden
backdrop-filter blur(calc(var(--blur) * 0.25))
transform translate3d(0, 0, var(--depth))
transition transform var(--transition), backdrop-filter var(--transition)
&__shadow
--shadow-fill 'hsla(0, 0%, 0%, %s)' % var(--shadow-alpha)
--fill var(--shadow-fill)
background var(--shadow-bg)
filter blur(var(--blur))
transition filter var(--transition)
&__text
position absolute
width 1px
height 1px
padding 0
margin -1px
overflow hidden
clip rect(0, 0, 0, 0)
white-space nowrap
border-width 0
&__shine
--shine-size calc(var(--size) * 0.5)
background var(--shine)
border-radius 50%
height var(--shine-size)
filter blur(var(--shine-blur)) brightness(1.25)
min-height 75px
min-width 75px
position absolute
left 0
top 0
transform translate3d(-50%, -50%, 1vmin) translate(calc(var(--x, -150) * 1%), calc(var(--y, -150) * 1%))
width var(--shine-size)
&__icon
height var(--icon-size)
fill var(--fill)
width var(--icon-size)
transition fill var(--transition)
&:active
--depth 0
--blur 0
--shadow-alpha 1
View Compiled
import gsap from 'https://cdn.skypack.dev/gsap'
const BUTTON = document.querySelector('.button')
const CONTENT = document.querySelector('.button__content')
const SHINE = document.querySelector('.button__shine')
const buttonSet = gsap.quickSetter(BUTTON, 'css')
const xySet = gsap.quickSetter(SHINE, 'css')
const LIMIT = 10
const UPDATE = ({x, y}) => {
const BOUNDS = CONTENT.getBoundingClientRect()
const POS_X = ((x - BOUNDS.x) / BOUNDS.width) * 200
const POS_Y = ((y - BOUNDS.y) / BOUNDS.height) * 200
xySet({
'--x': POS_X,
'--y': POS_Y
})
const xPercent = gsap.utils.mapRange(
0,
window.innerWidth,
-LIMIT,
LIMIT,
x
)
const yPercent = gsap.utils.mapRange(
0,
window.innerHeight,
-LIMIT,
LIMIT,
y
)
buttonSet({
xPercent,
yPercent,
})
}
document.addEventListener('pointermove', UPDATE)
document.addEventListener('pointerdown', UPDATE)
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.