| 1 |
import { useEffect } from '@wordpress/element' |
| 2 |
|
| 3 |
export const useAnimatedHeight = (preview, blockHeight, ready) => { |
| 4 |
useEffect(() => { |
| 5 |
let raf1, raf2 |
| 6 |
if (!preview.current) return |
| 7 |
const p = preview.current |
| 8 |
const iframe = p?.querySelector('iframe[title]') |
| 9 |
if (!iframe) return |
| 10 |
const content = iframe.contentWindow.document.body |
| 11 |
const scale = preview.offsetWidth / 1400 |
| 12 |
iframe.style.maxHeight = `${blockHeight / scale}px` |
| 13 |
|
| 14 |
const handleIn = () => { |
| 15 |
if (!content?.offsetHeight) return |
| 16 |
// The live component changes over time so easier to query on demand |
| 17 |
const height = content.offsetHeight |
| 18 |
content.style.transitionDuration = Math.max(height * 3, 3000) + 'ms' |
| 19 |
raf1 = window.requestAnimationFrame(() => { |
| 20 |
content.style.top = Math.abs(height - blockHeight) * -1 + 'px' |
| 21 |
}) |
| 22 |
} |
| 23 |
const handleOut = () => { |
| 24 |
if (!content?.offsetHeight) return |
| 25 |
const height = content.offsetHeight |
| 26 |
content.style.transitionDuration = height / 1.5 + 'ms' |
| 27 |
raf2 = window.requestAnimationFrame(() => { |
| 28 |
content.style.top = 0 |
| 29 |
}) |
| 30 |
} |
| 31 |
|
| 32 |
p.addEventListener('focus', handleIn) |
| 33 |
p.addEventListener('mouseenter', handleIn) |
| 34 |
p.addEventListener('blur', handleOut) |
| 35 |
p.addEventListener('mouseleave', handleOut) |
| 36 |
return () => { |
| 37 |
window.cancelAnimationFrame(raf1) |
| 38 |
window.cancelAnimationFrame(raf2) |
| 39 |
p.removeEventListener('focus', handleIn) |
| 40 |
p.removeEventListener('mouseenter', handleIn) |
| 41 |
p.removeEventListener('blur', handleOut) |
| 42 |
p.removeEventListener('mouseleave', handleOut) |
| 43 |
} |
| 44 |
}, [blockHeight, preview, ready]) |
| 45 |
} |
| 46 |
|