Skip to content

Instantly share code, notes, and snippets.

@jesperlandberg
Created January 19, 2022 12:53
Show Gist options
  • Save jesperlandberg/bafa6cf5e1ba2ab0d9c12d5888323939 to your computer and use it in GitHub Desktop.
Save jesperlandberg/bafa6cf5e1ba2ab0d9c12d5888323939 to your computer and use it in GitHub Desktop.
import gsap from 'gsap'
export default {
data() {
return {
scroll: 0,
scrollCache: null,
scrollResizing: false,
scrollInited: false,
scrollElems: []
}
},
mounted() {
setTimeout(() => {
this.scrollInited = true
this.scrollElems = [...document.querySelectorAll('[data-smooth]')]
this.setSections()
this.addEvents()
})
},
destroyed() {
this.removeEvents()
},
computed: {
bounds() {
return this.$store.state.app.bounds
}
},
methods: {
addEvents() {
this.$nuxt.$on('tick', this.tick)
this.$nuxt.$on('on-resize', this.resize)
},
setSections() {
const { wh } = this.$store.state.app.bounds
const total = this.scrollElems.length - 1
this.scrollCache = this.scrollElems.map((el, i) => {
const ySet = gsap.quickSetter(el, 'y', 'px')
ySet(0)
const speed = parseFloat(el.dataset.smooth || 1)
const { top, bottom } = el.getBoundingClientRect()
const start = top - wh
const end = bottom
i === total && this.$store.commit('app/SET_MAXSCROLL', bottom - wh)
return { el, start, end, ySet, speed, out: true }
})
},
tick({ cY }) {
this.scroll = cY
if (this.bounds.maxScroll <= this.bounds.wh || this.scrollResizing) return
this.transformSections()
},
transformSections() {
for (let i = 0; i < this.scrollCache.length; i++) {
const c = this.scrollCache[i]
const { ySet, start, end, speed } = c
const isVisible = this.inView(start, end, speed)
if (isVisible || this.scrollResizing) {
c.out && (c.out = false)
ySet(-(this.scroll * speed))
} else if (!c.out) {
c.out = true
ySet(-(this.scroll * speed))
}
}
},
inView(start, end, speed) {
const scroll = this.scroll * speed
return scroll > start && scroll < end
},
resize() {
this.scrollResizing = true
this.setSections()
this.$nuxt.$emit('on-resize-reset')
this.transformSections()
this.scrollResizing = false
},
removeEvents() {
this.$nuxt.$off('tick', this.tick)
this.$nuxt.$off('on-resize', this.resize)
this.$nuxt.$emit('scroll-reset')
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment