basic setup
This commit is contained in:
46
composables/useScrollProgress.js
Normal file
46
composables/useScrollProgress.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import {
|
||||
useElementBounding,
|
||||
useIntersectionObserver,
|
||||
useWindowSize,
|
||||
} from '@vueuse/core'
|
||||
import { ref } from 'vue'
|
||||
import { mapRange, clamp } from '@/libs/math'
|
||||
import useLenis from '@/composables/useLenis'
|
||||
|
||||
const { height: wHeight } = useWindowSize()
|
||||
|
||||
export const useScrollProgress = (el, callback, entry = 0.5, exit = 0.5) => {
|
||||
const isActive = ref(true)
|
||||
const smoothProgress = ref(0)
|
||||
|
||||
const { height, top } = useElementBounding(el)
|
||||
|
||||
const isIntersected = ref(false)
|
||||
const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => {
|
||||
isIntersected.value = isIntersecting
|
||||
})
|
||||
|
||||
useLenis(({ scroll }) => {
|
||||
if (!isActive.value) return
|
||||
if (!height.value || !wHeight.value) return
|
||||
if (!isIntersected.value) return
|
||||
|
||||
const pageTop = scroll + top.value
|
||||
|
||||
const start = pageTop - wHeight.value * entry
|
||||
const end = pageTop + height.value - wHeight.value * exit
|
||||
|
||||
let rawProgress = mapRange(start, end, scroll, 0, 1)
|
||||
rawProgress = clamp(0, rawProgress, 1)
|
||||
|
||||
smoothProgress.value += (rawProgress - smoothProgress.value) * 0.1
|
||||
callback?.(smoothProgress.value)
|
||||
})
|
||||
|
||||
const destroy = () => {
|
||||
isActive.value = false
|
||||
stop?.()
|
||||
}
|
||||
|
||||
return { destroy }
|
||||
}
|
||||
Reference in New Issue
Block a user