<script setup>
// The function
function map(x, a1, a2, b1, b2){
return ((x - a1) * (b2 - b1)) / (a2 - a1) + b1;
}
// Needed variables
const maxScroll = ref(500)
const minWidth = ref(25)
const maxWidth = ref(80)
const currentWidth = ref(25)
// Flag to avoid multiple updates within the same animation cycle
let ticking = false;
// Function updating the width based on scroll position
const updateWidth = () => {
const scroll = window.scrollY
// Clamp the scroll value between 0 and maxScroll.value
const clamped = Math.min(Math.max(scroll, 0), maxScroll.value)
// Convert the scroll position into a width using the map function
currentWidth.value = map(clamped, 0, maxScroll.value, minWidth.value, maxWidth.value)
// Allow new updates on the next frame
ticking = false
}
// Function running every time a scroll occurs
const onScroll = () => {
// Only update if a requestAnimationFrame cycle is not already running
if (!ticking) {
requestAnimationFrame(updateWidth)
ticking = true
}
}
// The event listener is added when the component mounts
onMounted(() => {
window.addEventListener('scroll', onScroll)
})
// The event listener is removed when the component unmounts
onUnmounted(() => {
window.removeEventListener('scroll', onScroll)
})
</script>
<template>
<div :style="{width: currentWidth + '%'}">
Content
</div>
</template>