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 (