API/client/src/components/Meteor/MeteorRegion.jsx
2026-04-03 23:42:11 +03:00

59 lines
1.6 KiB
JavaScript

import React, { useState, useRef, useEffect, useCallback } from "react";
import "./MeteorRegion.css";
const MeteorRegion = ({ children, className = "", maxHeight }) => {
const [scrollProgress, setScrollProgress] = useState(0);
const [isVisible, setIsVisible] = useState(false);
const containerRef = useRef(null);
const updateScroll = useCallback(() => {
const el = containerRef.current;
if (!el) return;
const { scrollTop, scrollHeight, clientHeight } = el;
const progress = scrollTop / (scrollHeight - clientHeight);
setScrollProgress(isNaN(progress) ? 0 : progress);
setIsVisible(scrollHeight > clientHeight);
}, []);
useEffect(() => {
const el = containerRef.current;
if (!el) return;
const resizeObserver = new ResizeObserver(updateScroll);
resizeObserver.observe(el);
el.addEventListener("scroll", updateScroll);
updateScroll();
return () => {
resizeObserver.disconnect();
el.removeEventListener("scroll", updateScroll);
};
}, [updateScroll]);
return (
<div className={`meteor-region-wrapper ${className}`} style={{ maxHeight }}>
<div className="meteor-region-content" ref={containerRef}>
{children}
</div>
{isVisible && (
<div className="meteor-track-local">
<div
className="meteor-slider-local"
style={{
transform: `translateY(${scrollProgress * (containerRef.current?.clientHeight - 70)}px)`,
}}
>
<div className="meteor-glow-local" />
</div>
</div>
)}
</div>
);
};
export default MeteorRegion;