Skip to content

Instantly share code, notes, and snippets.

@jesperlandberg
Created November 27, 2021 18:22
Show Gist options
  • Save jesperlandberg/419acd2eea299417b084b09e4bab02bb to your computer and use it in GitHub Desktop.
Save jesperlandberg/419acd2eea299417b084b09e4bab02bb to your computer and use it in GitHub Desktop.
import gsap from 'gsap'
import { evt, utils } from '@/core'
const { qs, qsa, rect } = utils
export default function () {
const el = qs('.js-clip-menu')
const mask = qs('.js-clip-menu-mask', el)
const items = qsa('.js-clip-menu-link', el)
const clip = {
left: 0,
right: 0,
}
const maskBounds = rect(mask)
const cache = items.map(item => {
const { left, width } = rect(item)
const cl = left - maskBounds.left
const cr = (maskBounds.left + maskBounds.width) - (left + width)
return { cl, cr }
})
const tl = gsap.timeline({
paused: true,
onUpdate: () => gsap.set(mask, {
clipPath: `inset(3px ${clip.right}px 3px ${clip.left}px round 999px)`,
})
})
let lastIdx = 0
let currentIdx = 0
function onClick({ currentTarget }) {
lastIdx = currentIdx
currentIdx = items.indexOf(currentTarget)
const { cl, cr } = cache[currentIdx]
const easings = lastIdx >= currentIdx ? ['expo', 'power3'] : ['power3', 'expo']
tl.clear()
.to(clip, {
left: cl,
duration: 1,
ease: easings[0],
})
.to(clip, {
right: cr,
duration: 1,
ease: easings[1]
}, 0)
.restart()
}
function mount() {
evt.on('click', items, onClick)
}
function unmount() {
evt.off('click', items, onClick)
}
mount()
return {
unmount
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment