Skip to content

Instantly share code, notes, and snippets.

@mike-at-redspace
Created August 10, 2023 07:12
Show Gist options
  • Save mike-at-redspace/77ba4fb225b68c10dd0b601580b9b0b4 to your computer and use it in GitHub Desktop.
Save mike-at-redspace/77ba4fb225b68c10dd0b601580b9b0b4 to your computer and use it in GitHub Desktop.
DynamicPicture - useResponsiveImage
/**
* React hook to get responsive image dimensions
*
* DynamicPicture could use the height and width from sources[0] as initial dimensions (SSR)??
*
* @param {string} imageUrl - Image src url
* @param {object} initialDimensions - Initial dimensions for SSR
* @returns {{dimensions: {width: number, height: number}, imageRef}} - Image dimensions and ref
*/
const useResponsiveImage = (imageUrl, initialDimensions) => {
const [dimensions, setDimensions] = useState(
initialDimensions ?? { width: 0, height: 0 }
)
const imageRef = useRef()
const isClient = typeof window !== 'undefined'
useEffect(() => {
if (!isClient) return
const handleResize = () => {
if (imageRef.current) {
const { width, height } = imageRef.current.getBoundingClientRect()
setDimensions({ width, height })
}
}
const debouncedHandleResize = debounce(handleResize, 300)
window.addEventListener('resize', debouncedHandleResize)
handleResize()
return () => {
window.removeEventListener('resize', debouncedHandleResize)
}
}, [imageUrl])
return {
dimensions,
imageRef
}
}
/**
* Debounce utility for throttle window resize
*
* @param {Function} fn - Handler function
* @param {number} delay - Debounce delay in ms
* @returns {Function} - Debounced function
*/
const debounce = (fn, delay) => {
let timeoutId
return (...args) => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => {
fn(...args)
}, delay)
}
}
export default useResponsiveImage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment