Spaces:
Sleeping
Sleeping
| import { useState, useEffect, useCallback, useRef } from 'react'; | |
| /** | |
| * Combined hook for device detection and canvas management | |
| * @returns {Object} Device and canvas management utilities | |
| */ | |
| const useDeviceAndCanvas = () => { | |
| // Device detection state | |
| const [isMobile, setIsMobile] = useState(false); | |
| const [isMac, setIsMac] = useState(false); | |
| // Canvas management state | |
| const [canvasWidth, setCanvasWidth] = useState(640); | |
| const [canvasHeight, setCanvasHeight] = useState(480); | |
| const [videoAspectRatio, setVideoAspectRatio] = useState(4/3); | |
| const isComponentMounted = useRef(true); | |
| // Device detection effect | |
| useEffect(() => { | |
| isComponentMounted.current = true; | |
| const checkMobile = () => { | |
| const mobile = window.innerWidth < 768; | |
| setIsMobile(mobile); | |
| }; | |
| checkMobile(); | |
| window.addEventListener('resize', checkMobile); | |
| // Check if user is on Mac | |
| if (typeof navigator !== 'undefined') { | |
| setIsMac(navigator.platform.includes('Mac')); | |
| } | |
| return () => { | |
| isComponentMounted.current = false; | |
| window.removeEventListener('resize', checkMobile); | |
| }; | |
| }, []); | |
| // Function to update canvas size based on container width and video aspect ratio | |
| const updateCanvasSize = useCallback((aspectRatio) => { | |
| if (!isComponentMounted.current) return; | |
| const containerWidth = document.querySelector('.canvas-container')?.clientWidth || window.innerWidth; | |
| const windowHeight = window.innerHeight; | |
| // Set maximum dimensions for the canvas | |
| const maxWidth = Math.min(containerWidth, isMobile ? 640 : 960); | |
| // For mobile, limit height to 70% of viewport height to prevent excessive scrolling | |
| const maxHeight = isMobile ? windowHeight * 0.7 : windowHeight * 0.8; | |
| // Calculate dimensions maintaining aspect ratio within constraints | |
| let width = maxWidth; | |
| let height = width / aspectRatio; | |
| // If height exceeds max height, recalculate width to maintain aspect ratio | |
| if (height > maxHeight) { | |
| height = maxHeight; | |
| width = height * aspectRatio; | |
| } | |
| // Ensure width doesn't exceed container | |
| if (width > containerWidth) { | |
| width = containerWidth; | |
| height = width / aspectRatio; | |
| } | |
| // Round dimensions to prevent subpixel rendering issues | |
| setCanvasWidth(Math.round(width)); | |
| setCanvasHeight(Math.round(height)); | |
| }, [isMobile]); | |
| return { | |
| // Device detection | |
| isMobile, | |
| isMac, | |
| // Canvas management | |
| canvasWidth, | |
| canvasHeight, | |
| videoAspectRatio, | |
| setVideoAspectRatio, | |
| updateCanvasSize, | |
| isComponentMounted | |
| }; | |
| }; | |
| export default useDeviceAndCanvas; |