website refactor
This commit is contained in:
@@ -1,125 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState, RefObject } from 'react';
|
||||
|
||||
/**
|
||||
* Calculate scroll progress (0-1) based on element's position in viewport
|
||||
* @param ref - Reference to the element to track
|
||||
* @param offset - Offset from viewport edges (0-1, default 0.1)
|
||||
* @returns progress value between 0 and 1
|
||||
*/
|
||||
export function useScrollProgress(ref: RefObject<HTMLElement | null>, offset: number = 0.1): number {
|
||||
const [progress, setProgress] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref.current) return;
|
||||
|
||||
let rafId: number;
|
||||
|
||||
const calculateProgress = () => {
|
||||
if (!ref.current) return;
|
||||
|
||||
const rect = ref.current.getBoundingClientRect();
|
||||
const viewportHeight = window.innerHeight;
|
||||
const scrollY = window.scrollY;
|
||||
const documentHeight = document.documentElement.scrollHeight;
|
||||
|
||||
// Element enters viewport from bottom
|
||||
const enterPoint = viewportHeight * (1 - offset);
|
||||
// Element reaches top of viewport
|
||||
const exitPoint = viewportHeight * offset;
|
||||
|
||||
// Calculate progress: 0 when entering, 1 at 30% viewport (accelerated)
|
||||
const elementCenter = rect.top + rect.height / 2;
|
||||
const totalDistance = enterPoint - exitPoint;
|
||||
const currentDistance = enterPoint - elementCenter;
|
||||
|
||||
// Accelerate progress to reach 1.0 at 30% viewport height
|
||||
// Scale factor: 1.67 makes progress reach 1.0 at ~30% instead of 50%
|
||||
const rawProgress = (currentDistance / totalDistance) * 1.67;
|
||||
let clampedProgress = Math.max(0, Math.min(1, rawProgress));
|
||||
|
||||
// At bottom of page - ensure elements near bottom can reach 100%
|
||||
// Only apply if we're at the very bottom AND this element is below the fold
|
||||
if (scrollY + viewportHeight >= documentHeight - 50 && rect.top < viewportHeight) {
|
||||
clampedProgress = Math.max(clampedProgress, 1);
|
||||
}
|
||||
|
||||
setProgress(clampedProgress);
|
||||
};
|
||||
|
||||
const handleScroll = () => {
|
||||
if (rafId) {
|
||||
cancelAnimationFrame(rafId);
|
||||
}
|
||||
rafId = requestAnimationFrame(calculateProgress);
|
||||
};
|
||||
|
||||
// Initial calculation
|
||||
calculateProgress();
|
||||
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
window.addEventListener('resize', handleScroll, { passive: true });
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll);
|
||||
window.removeEventListener('resize', handleScroll);
|
||||
if (rafId) {
|
||||
cancelAnimationFrame(rafId);
|
||||
}
|
||||
};
|
||||
}, [ref, offset]);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate parallax offset based on scroll position
|
||||
* @param ref - Reference to the element to track
|
||||
* @param speed - Parallax speed multiplier (default 0.5)
|
||||
* @returns offset in pixels
|
||||
*/
|
||||
export function useParallax(ref: RefObject<HTMLElement | null>, speed: number = 0.5): number {
|
||||
const [offset, setOffset] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref.current) return;
|
||||
|
||||
let rafId: number;
|
||||
|
||||
const calculateOffset = () => {
|
||||
if (!ref.current) return;
|
||||
|
||||
const rect = ref.current.getBoundingClientRect();
|
||||
const viewportHeight = window.innerHeight;
|
||||
|
||||
// Calculate offset based on element position relative to viewport
|
||||
const scrolled = viewportHeight - rect.top;
|
||||
const parallaxOffset = scrolled * speed;
|
||||
|
||||
setOffset(parallaxOffset);
|
||||
};
|
||||
|
||||
const handleScroll = () => {
|
||||
if (rafId) {
|
||||
cancelAnimationFrame(rafId);
|
||||
}
|
||||
rafId = requestAnimationFrame(calculateOffset);
|
||||
};
|
||||
|
||||
calculateOffset();
|
||||
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
window.addEventListener('resize', handleScroll, { passive: true });
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll);
|
||||
window.removeEventListener('resize', handleScroll);
|
||||
if (rafId) {
|
||||
cancelAnimationFrame(rafId);
|
||||
}
|
||||
};
|
||||
}, [ref, speed]);
|
||||
|
||||
return offset;
|
||||
}
|
||||
Reference in New Issue
Block a user