Open jordanlambrecht opened 2 years ago
@Gamote Any ideas?
@michax @mattvague @PatrickDesign Sorry for the pings, but this is pretty mission-critical for me
In what way is it not working?
I'm assuming the fact that you're defining a react component within another react component and using dynamic imports doesn't cause the issue.
@PatrickDesign Ha, I probably need to separate those components o.O The animation will play just fine. Everything works with no errors. The only issue is the segments part. It simply does not listen to the input and plays the whole animation straight through each loop.
Could you use the onLoopComplete method to update your segment array to be the shortened one after the first loop? And use the initialSegment
prop instead of playSegments
.
Something like:
// Defined statically outside of any functions (to keep a stable reference https://lottiereact.com/#initialsegment)
const firstLoopSegment = [0, 23]
const secondLoopSegment = [24, 95]
...
const [activeSegment, setActiveSegment] = useState(firstLoopSegment)
const onLoopComplete = () => {
setActiveSegment(secondLoopSegment)
}
...
<Lottie onLoopComplete={onLoopComplete} initialSegment={activeSegment} ... />
Like this? Because no dice if so =/
import lottie from 'lottie-web'
interface LottieProps {
animationData: any
width: number
height: number
onLoopComplete: any
initialSegment: any
}
const firstLoopSegment = [0, 23]
const secondLoopSegment = [24, 95]
const Lottie = ({ animationData }: LottieProps) => {
const element = useRef<HTMLDivElement>(null)
const lottieInstance = useRef<any>()
useEffect(() => {
if (element.current) {
lottieInstance.current?.destroy()
lottieInstance.current = lottie.loadAnimation({
container: element.current,
renderer: 'svg',
loop: true,
autoplay: true,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
animationData: animationData,
})
}
return () => {
lottieInstance.current?.destroy()
lottieInstance.current = null
}
}, [animationData])
return <div style={{ height: '100%', width: '100%' }} ref={element} />
}
const PageHeader_VariableHeight = ({ animationData }) => {
const [activeSegment, setActiveSegment] = useState(firstLoopSegment)
const onLoopComplete = () => {
setActiveSegment(secondLoopSegment)
}
return (
<Lottie
animationData={animationData}
width={100}
height={100}
onLoopComplete={onLoopComplete}
initialSegment={activeSegment}
/>
)
}
export default PageHeader_VariableHeight
AHA! I got it!
import lottie from 'lottie-web'
interface LottieProps {
animationData: any
width: number
height: number
}
const Lottie = ({ animationData }: LottieProps) => {
const element = useRef<HTMLDivElement>(null)
const lottieInstance = useRef<any>()
useEffect(() => {
if (element.current) {
lottieInstance.current?.destroy()
lottieInstance.current = lottie.loadAnimation({
container: element.current,
renderer: 'svg',
loop: true,
// autoplay: true,
rendererSettings: {
preserveAspectRatio: 'xMidYMid slice',
},
animationData: animationData,
})
}
lottieInstance.current.playSegments(
[
[0, 23],
[24, 95],
],
true,
)
return () => {
lottieInstance.current?.destroy()
lottieInstance.current = null
}
}, [animationData])
return <div style={{ height: '100%', width: '100%' }} ref={element} />
}
const PageHeader_VariableHeight = ({ animationData }) => {
return <Lottie animationData={animationData} width={100} height={100} />
}
export default PageHeader_VariableHeight
I'm trying to have my lottie animation play the first 23 frames, and then skip them when it loops back and restarts and play frames 24-95 indefinitely. I'm dumb and can't seem to figure out how to make this work. Example here of it implemented with react-lottie-player (I'm switching over because you're more active and cool)
Here's my code that isn't working: