Reputation: 11853
I have a Lottie animation that is rendered using react-lottie
(https://www.npmjs.com/package/react-lottie)
import Lottie from 'react-lottie'
import animationData from './path/to/animation.json'
const MyComponent = () => {
const myOptions = {
loop: true,
autoplay: true,
renderer: 'canvas',
animationData: animationData
}
return (
<div>
...other stuff
<Lottie options={myOptions} width={1000} height={500} />
</div>
)
}
The animation displays and plays fine.
The issue is that when resizing the browser, the animation shrinks and squishes and does not preserve its original aspect ratio. If I do a page refresh after shrinking the browser, the animation is then rendered correctly. It is only when the resizing is actively occurring that the aspect ratio is off.
I have tried adding:
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice' // also tried 'xMidYMid meet'
}
to my options but that does not work either.
The only other thing I can think of is to attach a resize
event listener to the window which will in turn call lottie.resize()
useEffect(() => {
window.addEventListener('resize', ??)
}, [])
The stuff in ??
is where I get stuck. I know that using lottie-web
, I have direct access to a lottie.resize()
function. However, when using react-lottie
, how do I call/access the resize function?
Any help would be greatly appreciated.
Edit: I have been asked to add an example animation JSON so it is here: https://pastebin.com/gXCEhKaR
Upvotes: 1
Views: 3006
Reputation: 181
Yes, thank you, I started it at home, but you have the width and height values set for the Lottie component. If you want Lottie to change its size depending on the size of the screen, then you need to add a hook to change the screen.
Hook resize
export function useSizeComponents (ref) {
const [size, setSize] = useState([0, 0])
useLayoutEffect(() => {
function updateSize () {
let newSize = [window.innerWidth, window.innerHeight]
if (ref?.current) {
newSize = [ref.current.offsetWidth, ref.current.offsetHeight]
}
setSize(newSize)
}
window.addEventListener('resize', updateSize)
updateSize()
return () => window.removeEventListener('resize', updateSize)
}, [])
return size
}
Your component
const MyComponent = () => {
const [width, height] = useSizeComponents()
const scaleLottie = 0.5
const myOptions = {
loop: true,
autoplay: true,
renderer: 'canvas',
animationData: animationData,
}
const control = useMemo(() => {
if (!width) return null
const xMidYMid = 0.5
const sizeComponent = {
width: width * scaleLottie,
height: width * scaleLottie * xMidYMid
}
return <Lottie key={width} options={myOptions} {...sizeComponent} />
}, [width])
return (
<div>
...other stuff
{control}
</div>
)
}
Upvotes: 3