46 lines
1.8 KiB
JavaScript
46 lines
1.8 KiB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
|
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
import { throttle } from "lodash";
|
|
import styles from "./with-observation.module.scss";
|
|
export const WithObservation = ({ children, onShow, onHide, onReady, ...props }) => {
|
|
const videoContainerRef = useRef(null);
|
|
const playerRef = useRef(null);
|
|
const [isVisible, setIsVisible] = useState(false);
|
|
const handlePlayer = useCallback((player) => {
|
|
playerRef.current = player;
|
|
onReady && onReady(player);
|
|
}, []);
|
|
const hide = useCallback(() => {
|
|
onHide && onHide(playerRef.current);
|
|
}, [onHide]);
|
|
const show = useCallback(() => {
|
|
onShow && onShow(playerRef.current);
|
|
}, [onShow]);
|
|
// Throttle для обработки видимости
|
|
const handleVisibility = throttle((entry) => {
|
|
if (entry.isIntersecting && !isVisible) {
|
|
setIsVisible(true);
|
|
show();
|
|
}
|
|
else if (!entry.isIntersecting && isVisible) {
|
|
setIsVisible(false);
|
|
hide();
|
|
}
|
|
}, 200);
|
|
useEffect(() => {
|
|
const observer = new IntersectionObserver(([entry]) => handleVisibility(entry), {
|
|
threshold: 0.75,
|
|
});
|
|
if (videoContainerRef.current) {
|
|
observer.observe(videoContainerRef.current);
|
|
}
|
|
return () => {
|
|
if (videoContainerRef.current) {
|
|
observer.unobserve(videoContainerRef.current);
|
|
}
|
|
handleVisibility.cancel();
|
|
};
|
|
}, [handleVisibility]);
|
|
return (_jsx("div", { ref: videoContainerRef, className: styles.videoArea, children: React.cloneElement(children, { ...props, onReady: handlePlayer }) }));
|
|
};
|
|
//# sourceMappingURL=index.js.map
|