#reactjs #lottie
Вопрос:
У меня есть анимация Лотти, которая визуализируется с использованием 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>
)
}
Анимация отображается и воспроизводится нормально.
Проблема в том, что при изменении размера браузера анимация сжимается и сжимается и не сохраняет свое первоначальное соотношение сторон. Если я обновлю страницу после сжатия браузера, анимация будет отображаться правильно. Только при активном изменении размера соотношение сторон отключается.
Я попытался добавить:
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice' // also tried 'xMidYMid meet'
}
к моим вариантам, но это тоже не работает.
Единственное, о чем я могу подумать, это прикрепить прослушиватель resize
событий к окну, которое, в свою очередь, вызовет lottie.resize()
useEffect(() => {
window.addEventListener('resize', ??)
}, [])
Все дело в ??
том, где я застрял. Я знаю , что при использовании lottie-web
у меня есть прямой доступ к lottie.resize()
функции. Однако при использовании react-lottie
, как я могу вызвать/получить доступ к функции изменения размера?
Любая помощь была бы очень признательна.
Редактировать: Меня попросили добавить пример анимации JSON, поэтому он здесь: https://pastebin.com/gXCEhKaR
Комментарии:
1. Привет, пожалуйста, добавьте пример ваших данных
2. @AiratMustaev Я отредактировал свой пост, чтобы включить пример анимационных данных
Ответ №1:
Да, спасибо, я начал это дома, но у вас есть значения ширины и высоты, установленные для компонента Лотти. Если вы хотите, чтобы Лотти меняла свой размер в зависимости от размера экрана, вам нужно добавить крючок для изменения экрана.
Изменение размера крючка
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
}
Ваш компонент
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>
)
}