handspew / hooks /useDeviceAndCanvas.js
Tina Tarighian
mobile ratio
5f82b57
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;