React Spring — tracing SVG on scroll?

Hey guys, been tackling React Spring this past week and have learned the basics pretty well, however, I’m struggling to have this last bit of functionality work. I essentially want to have an SVG tracing animation when the element is in the viewport. So, I have working examples of a tracing SVG and a working example of React Spring animations to fire when they enter the viewport:

SVG tracing animation:

  // SVG animation
  const svgSpring = useSpring({
    from: { x: 0, opacity: 0 },
    to: async next => {
      await next({ x: 120, opacity: 1 })
    },
    delay: 3000,
    config: { tension: 20, friction: 10 }
  })

//HTML returned using the above Spring
      <animated.svg
        viewBox="0 0 25 25"
        className={`lightning-bolt ${flicker ? 'flicker' : ''}`}
        style={svgSpring}
        strokeDashoffset={svgSpring.x}
        preserveAspectRatio="none"
      >
        <path
          fill="none"
          stroke="gold"
          strokeWidth=".5"
          strokeDasharray="60"
          height="100%"
          width="100%"
          d="M7 2v11h3v9l7-12h-4l4-8z"
        />
      </animated.svg>

Here is a working example of an element entering the viewport and then firing the animation:

<VisibilitySensor>
  {({ isVisible }) => (
    <div className="projects-title-container">
      <Spring
        delay={300}
        to={{
          transform: isVisible ? 'translate(-50px)' : 'translate(50px)',
          opacity: isVisible ? 1 : 0,
        }}
      >
        {({ transform, opacity }) =>
          <h1
            className="section-title projects-title"
            style={{transform, opacity}}
          >
            Projects
          </h1>
        }
      </Spring>
    </div>
  )}
</VisibilitySensor>

The above, I am using VisibilitySensor and passing the props of isVisible. I am very confused as to how to pass that prop through to an SVG that relies on both the from AND to prop?

This is what I have currently, that traces the SVG, but it fires on page load as I am not using isVisible yet and unsure of how to implement it. I have tried using ternary operators in the from and to props, but if I remove the from entirely and do a ternary in the to={{}} prop, the SVG doesn’t even load.

      <VisibilitySensor>
        {({ isVisible }) => (
          <Spring
            delay={0}
            from={{
              x: 60,
              opacity: 0
            }}
            to={{
              x: 120,
              opacity: 1
            }}
            config={{
              tension: 40,
              friction: 10
            }}
          >
            {({ x, opacity }) => 
              <svg
                viewBox="0 0 18 23"
                className="lightning-strike"
                style={{x, opacity}}
                strokeDashoffset={x}
                preserveAspectRatio="none"
              >
                <path
                  fill="none"
                  stroke="rgba(255, 215, 0, 0.5)"
                  strokeWidth=".1"
                  strokeDasharray="60"
                  height="100%"
                  width="100%"
                  d="M7 2v11h3v9"
                />
              </svg>
            }
          </Spring>
        )}
      </VisibilitySensor>

Any help is much appreciated here. Thanks!

So, I went about a different way and solved it. Here is tracing an SVG on scroll:

import React, { useState, createRef, useEffect } from 'react'
import styled from 'styled-components'
import { useInView } from 'react-intersection-observer'

const SvgComponent = (props) => {
  const [inViewRef, inView] = useInView({
    triggerOnce: true
  })
  const pathRef = createRef()
  const [pathLength, setPathLength] = useState()

  useEffect(
    () => {
      if (pathRef.current) {
        setPathLength(pathRef.current.getTotalLength())
      }
    },
    [pathRef]
  )

  return (
    <Wrapper
      ref={inViewRef}
      pathLength={pathLength}
    >
      <svg
        className={inView ? 'about-animated visible' : 'about-animated'}
        viewBox='0 0 15 24'
        {...props}
      >
        <path
          height="100%"
          width="100%"
          ref={pathRef}
          d="M7 2v11h3v9"
          fill='none'
          stroke='rgba(255, 215, 0, 0.5)'
          strokeWidth={0.07}
        />
      </svg>
      <svg
        className={inView ? 'about-animated-two visible' : 'about-animated-two'}
        viewBox='0 0 15 24'
        {...props}
      >
        <path
          height="100%"
          width="100%"
          ref={pathRef}
          d="M7 2v11h3v9"
          fill='none'
          stroke='rgba(255, 255, 0, 0.5)'
          strokeWidth={0.03}
        />
      </svg>
    </Wrapper>
  )
}

const Wrapper = styled.div`
  .about-animated {
    stroke-dasharray: ${(props) => props.pathLength};
    stroke-dashoffset: ${(props) => props.pathLength};
    max-width: 100%;
    height: auto;
    position: absolute;
    top: 9%;
    right: 0;
    z-index: 0;
    transform: rotate(-60deg);
  }
  .about-animated-two {
    stroke-dasharray: ${(props) => props.pathLength};
    stroke-dashoffset: ${(props) => props.pathLength};
    max-width: 100%;
    height: auto;
    position: absolute;
    top: 10%;
    right: 0;
    z-index: 0;
    transform: rotate(-60deg);
  }
  .about-animated.visible, .about-animated-two.visible {
    animation: draw .2s linear forwards;
    animation-delay: 2s;
  }
  @keyframes draw {
    from {
      stroke-dashoffset: ${(props) => props.pathLength};
    }
    to {
      stroke-dashoffset: 0;
    }
  }

  @media (min-width: 600px) {
    .about-animated {
      top: -5%;
    }
    .about-animated-two {
      top: -4%;
    }
  }
export default SvgComponent