sigit.io/src/hooks/useScale.tsx

64 lines
1.4 KiB
TypeScript
Raw Normal View History

import { useEffect, useState } from 'react'
import { singletonHook } from 'react-singleton-hook'
const noScaleInit = {
to: (_: number, v: number) => v,
from: (_: number, v: number) => v
}
const getInnerContentWidth = () => {
// Fetch the first container element we find
const element = document.querySelector('#content-preview')
if (element) {
const style = getComputedStyle(element)
// Calculate width without padding
const widthWithoutPadding =
element.clientWidth - parseFloat(style.padding) * 2
return widthWithoutPadding
}
// Default value
return 620
}
const useScaleImpl = () => {
const [width, setWidth] = useState(getInnerContentWidth())
// Get the scale based on the original width
const scale = (originalWidth: number) => {
return width / originalWidth
}
// Get the original pixel value
const to = (originalWidth: number, value: number) => {
return value / scale(originalWidth)
}
// Get the scaled pixel value
const from = (originalWidth: number, value: number) => {
return value * scale(originalWidth)
}
const resize = () => {
setWidth(getInnerContentWidth())
}
useEffect(() => {
resize()
window.addEventListener('resize', resize)
return () => {
window.removeEventListener('resize', resize)
}
}, [])
return { to, from }
}
export const useScale = singletonHook(noScaleInit, useScaleImpl, {
unmountIfNoConsumers: true
})