diff --git a/client/src/components/DraggableContainer.tsx b/client/src/components/DraggableContainer.tsx index 730fe5f..7028911 100644 --- a/client/src/components/DraggableContainer.tsx +++ b/client/src/components/DraggableContainer.tsx @@ -16,6 +16,8 @@ interface DraggableContainerProps { enableSnapping?: boolean; /** Автоматическое flex-выравнивание в зависимости от прижатого угла (по умолчанию false) */ autoAlign?: boolean; + /** Ограничить перетаскивание границами окна (по умолчанию false) */ + constrainToBounds?: boolean; /** Начальная позиция контейнера */ initialPosition?: Position; /** Отступ от краев экрана при снэпинге (по умолчанию 20px) */ @@ -41,6 +43,12 @@ interface DraggableContainerProps { * * * @example + * // С ограничением перетаскивания границами окна + * + * + * + * + * @example * // Без автоматического выравнивания (управляется вручную через className) * * @@ -50,6 +58,7 @@ export default function DraggableContainer({ children, enableSnapping = false, autoAlign = false, + constrainToBounds = false, initialPosition = { top: 20, right: 20 }, padding = 20, className = "", @@ -150,8 +159,20 @@ export default function DraggableContainer({ const deltaX = clientX - dragRef.current.startX; const deltaY = clientY - dragRef.current.startY; - const newTop = dragRef.current.initialPosition.top + deltaY; - const newLeft = dragRef.current.initialPosition.left + deltaX; + // Вычисляем новую позицию + let newTop = dragRef.current.initialPosition.top + deltaY; + let newLeft = dragRef.current.initialPosition.left + deltaX; + + // Ограничиваем позицию границами окна, если включено + if (constrainToBounds && containerRef.current) { + const containerWidth = containerRef.current.offsetWidth; + const containerHeight = containerRef.current.offsetHeight; + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + + newTop = Math.max(0, Math.min(newTop, windowHeight - containerHeight)); + newLeft = Math.max(0, Math.min(newLeft, windowWidth - containerWidth)); + } // Во время перетаскивания используем только top и left const newPosition = { diff --git a/client/src/components/PixelStreamingWrapper.tsx b/client/src/components/PixelStreamingWrapper.tsx index 91a8cc1..03893bf 100644 --- a/client/src/components/PixelStreamingWrapper.tsx +++ b/client/src/components/PixelStreamingWrapper.tsx @@ -28,9 +28,49 @@ export const PixelStreamingWrapper = ({ // Run on component mount: useEffect(() => { + // Сохраняем оригинальные методы console + const originalLog = console.log; + const originalInfo = console.info; + const originalWarn = console.warn; + + // Переопределяем console для фильтрации логов Pixel Streaming + console.log = (...args) => { + const message = args[0]?.toString() || ""; + if ( + !message.includes("[Info]") && + !message.includes("[Debug]") && + !message.includes("Stack:") + ) { + originalLog.apply(console, args); + } + }; + + console.info = (...args) => { + const message = args[0]?.toString() || ""; + if ( + !message.includes("[Info]") && + !message.includes("[Debug]") && + !message.includes("Stack:") + ) { + originalInfo.apply(console, args); + } + }; + + console.warn = (...args) => { + const message = args[0]?.toString() || ""; + if ( + !message.includes("[Info]") && + !message.includes("[Debug]") && + !message.includes("Stack:") + ) { + originalWarn.apply(console, args); + } + }; + if (videoParent.current) { // Attach Pixel Streaming library to videoParent element: const config = new Config({ initialSettings }); + const streaming = new PixelStreaming(config, { videoElementParent: videoParent.current, }); @@ -54,8 +94,20 @@ export const PixelStreamingWrapper = ({ } catch { // } + + // Восстанавливаем оригинальные методы console + console.log = originalLog; + console.info = originalInfo; + console.warn = originalWarn; }; } + + // Восстанавливаем console если компонент размонтируется до инициализации + return () => { + console.log = originalLog; + console.info = originalInfo; + console.warn = originalWarn; + }; }, []); return (