react-nativereact-native-reanimatedreact-native-svgreact-native-reanimated-v2

React-native-reanimated translate transition on React-native-svg group not working


I am trying to acheive a simple animation of a group of svg elements. The group should start off the top of the (landscape forced) viewport (translateY: -900) then transition in dropping from off the top of the screen into the viewport (translateY: 0). I am trying to do this with react-native-svg and react-native-reanimated (v2). Here is the code I have so far:

import React, { useEffect } from 'react'
import Svg, {
  G,
  Path,
  Defs,
  LinearGradient,
  Stop,
  Line,
} from 'react-native-svg'
import Animated, {
  useSharedValue,
  useAnimatedProps,
  withTiming,
  Easing,
} from 'react-native-reanimated'

const AnimatedGroup = Animated.createAnimatedComponent(G)

const Curtains = ({}) => {
  const vOffset = useSharedValue(-900)

  const config = {
    duration: 1500,
    easing: Easing.bezier(0.5, 0.01, 0, 1),
  }

  const animatedProps = useAnimatedProps(() => {
    return {
      translateY: withTiming(vOffset.value, config),
    }
  })

  const animateIn = () => {
    vOffset.value = 0
  }

  useEffect(() => {
    animateIn()
  }, [])

  return (
    <Svg
      width="100%"
      height="100%"
      viewBox="0 0 1600 900"
      // onLayout={() => animateIn()}
    >
      <AnimatedGroup id="bothCurtains" animatedProps={animatedProps}>
        // A whole bunch of sub-groups and path in here
      </AnimatedGroup>
    </Svg>
  )
}

export default Curtains

As you can see I've tried to trigger the animation using both useEffect and the onLayout event on the SVG element, neither seems to work - there is no transition occuring.

Apologies if I've missed something obvious, this is my first attempt at a react-native project. Im really enjoying it but this has me stumped. I beleieve my implementation is correct when compared with the examples shown on the Reanimated documentation but for some reason it does not work. I've created a test component that utilises useAnimatedStyle on a view element which works fine so Im satisfied the library is installed correctly and is working so it can only be my implementation. Any help would be greatly appreciated, if you need any more information dont hestiate to ask. Thanks in advance.


Solution

  • For the benefit of anyone else having this problem, the solution was so obvious as to be easily missed: Instead of applyting the transition to 'translateY' i applied it to 'y' and it worked first time.

    import React, { useEffect } from 'react'
    import Svg, {
      G,
      Path,
      Defs,
      LinearGradient,
      Stop,
      Line,
    } from 'react-native-svg'
    import Animated, {
      useSharedValue,
      useAnimatedProps,
      withTiming,
      Easing,
    } from 'react-native-reanimated'
    
    const AnimatedGroup = Animated.createAnimatedComponent(G)
    
    const Curtains = ({}) => {
      const vOffset = useSharedValue(-900)
    
      const config = {
        duration: 1500,
        easing: Easing.bezier(0.5, 0.01, 0, 1),
      }
    
      const animatedProps = useAnimatedProps(() => {
        return {
          y: withTiming(vOffset.value, config),
        }
      })
    
      const animateIn = () => {
        vOffset.value = 0
      }
    
      useEffect(() => {
        animateIn()
      }, [])
    
      return (
        <Svg
          width="100%"
          height="100%"
          viewBox="0 0 1600 900"
        >
          <AnimatedGroup id="bothCurtains" animatedProps={animatedProps}>
            // A whole bunch of sub-groups and path in here
          </AnimatedGroup>
        </Svg>
      )
    }
    
    export default Curtains
    

    I hope this helps somebody!