Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import TweenMax from 'gsap'
import event from 'dom-events'
import imagesLoaded from 'imagesloaded'
import lerp from '~/assets/js/functions/lerp'
export default class Smooth {
constructor(el) {
this.createBound()
this.content = el.querySelector('.js-scroll-content')
this.sections = [...this.content.querySelectorAll('.js-scroll-section')]
this.elems = [...this.content.querySelectorAll('[data-inertia')]
this.cache = {
sections: [],
elems: []
}
this.rAF = 0
this.setHeight()
}
init() {
this.setCache()
this.addEvents()
setTimeout(this.setHeight, 0)
this.preload()
}
createBound() {
['setHeight', 'scroll', 'run']
.forEach((fn) => this[fn] = this[fn].bind(this))
}
setHeight() {
TweenMax.set(document.body, {
height: this.content.clientHeight
})
}
preload() {
imagesLoaded(this.content, (instance) => {
this.setHeight()
})
}
setCache() {
this.sections.forEach((elem, i) => {
let section = {}
section.el = elem
section.sy = 0
section.ly = section.sy
section.ease = `0.15${i * 2}`
this.cache.sections.push(section)
})
this.elems.forEach((el) => {
let elem = {}
elem.el = el
elem.sy = 0
elem.ly = elem.sy
elem.val = elem.el.dataset.inertia
this.cache.elems.push(elem)
})
}
scroll() {
this.cache.sections.forEach((section) => {
section.sy = window.scrollY
})
this.cache.elems.forEach((elem) => {
elem.sy = window.scrollY
})
}
run() {
this.cache.sections.forEach((section) => {
section.ly = lerp(section.ly, section.sy, section.ease)
section.ly = Math.floor(section.ly * 100) / 100
TweenMax.set(section.el, { y: -section.ly })
})
this.cache.elems.forEach((elem) => {
elem.ly = lerp(elem.ly, elem.sy, 0.2)
elem.ly = Math.floor(elem.ly * 100) / 100
let sd = elem.sy - elem.ly
let acc = sd / window.innerHeight
let velo =+ acc
if (elem.val == 'skew') {
TweenMax.set(elem.el, { skewY: velo * 10 })
}
})
this.rAF = requestAnimationFrame(this.run)
}
on(requestAnimationFrame = true) {
requestAnimationFrame && this.requestAnimationFrame()
}
off(cancelAnimationFrame = true) {
cancelAnimationFrame && this.cancelAnimationFrame()
}
requestAnimationFrame() {
this.rAF = requestAnimationFrame(this.run)
}
cancelAnimationFrame() {
cancelAnimationFrame(this.rAF)
}
destroy() {
TweenMax.set(document.body, {
height: 'auto'
})
this.cache = {
sections: [],
elems: []
}
this.removeEvents()
}
addEvents() {
this.on()
event.on(window, 'resize', this.setHeight)
event.on(window, 'scroll', this.scroll)
}
removeEvents() {
this.off()
event.off(window, 'resize', this.setHeight)
event.off(window, 'scroll', this.scroll)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.