0

I'm trying to get a svg animation to start when it's in the viewport. It works but when adding transform properties the whole svg and not just the targeted class is affected.

import React, { useEffect, useRef, useState } from 'react';
import { ReactComponent as Animation2Svg } from '../assets/animation3.svg';
import './animation2.css';

export const Animation2 = () => {
  const animationRef = useRef();
  const [visibleAnimation, setVisibleAnimation] = useState();
  console.log('visibleAnimation', visibleAnimation);
  useEffect(() => {
    const observer = new IntersectionObserver((entries) => {
      const entry = entries[0];
      setVisibleAnimation(entry.isIntersecting);
      console.log('entry', entry);
    });
    observer.observe(animationRef.current);
    // console.log('animationRef', animationRef.current);
  }, []);

  return (
    <div
      ref={animationRef}
      className={`'animation_container' ${visibleAnimation ? 'lamp_fill' : ''}`}
    >
      <svg
        viewBox="0 0 960 960"
        fill="none"
        xmlns="http://www.w3.org/2000/svg"
      >
        <g id="lamp">
          <g id="_12">
            <g id="Group">
              <path
                className="lamp_fill"
                d="M 673.8,268.9 C 670.49,212.31 666.03,147.85 624.05,105.09 605.03,88.927 595.75,88.708 576.1,80.6 534.08,69.765 491.07,82.083 449.66,89.913 382.62,105.67 316.07,123.33 250.11,143.21 201.04,156.23 143.22,156.92 106.41,196.62 76.875,241.04 84.709,297.04 84.201,347.5 86.612,407.39 83.901,468 85.176,528.14 91.427,563.78 86.363,600.74 93.601,636.8 98.899,686.58 100.94,736.75 110.7,786 111.72,829.71 125.29,878.56 165.7,901.7 198.5,924.75 239.5,926.4 278.1,929.56 334.3,923.31 391.34,926.4 447.84,924.66 496.01,923.32 545.09,928.05 592.56,918.66 626.73,907.16 644.69,870.96 647.87,836.92 653.71,790.73 638.83,744.73 638.8,698.8 639.22,658.74 633.25,618.65 640.1,578.7 645.02,533.8 655.02,489.37 657.67,444.12 668.11,386.49 675.47,327.74 673.8,268.9 Z"
              fill="black"
              />
              <!--multiple path elements-->
            </g>
          </g>
        </g>
      </svg>
    </div>
  );
};

And this I the CSS that works (and without transform properties)

.lamp_fill {
  transform-box: fill-box;
  fill: transparent;
  animation: turnOn 6s linear infinite;
}


@keyframes turnOn {

  0%,
  30% {
    fill: transparent;
  }

  40%,
  100% {
    opacity: 1;
    fill: #ffb200;
  }
}

I have tried to move the ref so ut targets the svg directly but to be honest I have no idea how to solve this.

Here is a CodeSandbox to illustrate the problem https://codesandbox.io/s/hopeful-tree-xmd32p?file=/src/App.js

ccprog
  • 20,308
  • 4
  • 27
  • 44
Johanna
  • 3
  • 2
  • Please edit your question to include a [mcve] right here, not externally. [Reduce complexity.](https://meta.stackoverflow.com/questions/402684/how-to-reduce-complicated-code-on-runnable-code-example-sites-to-a-sensible-stac) – ccprog Jul 01 '22 at 11:12
  • @ccprog - thank you for your reply :) I tried to do so, but the svg makes the code too long. But I'll add back the code with the svg being imported. – Johanna Jul 01 '22 at 11:15
  • I have taken the liberty to add some relevant parts of the `` to your code. Still, I don't think I understand what you want to achieve. What should the animation look like in detail? What should be transformed, what should be recolored? – ccprog Jul 01 '22 at 11:59
  • Oh, and the `'` apostrophe around `animation_container` - is that a typo? That part is inside the backticks. – ccprog Jul 01 '22 at 12:03
  • @ccprog, I want to, for example, add a transition to the .lamp_fill without that transition having an impact on the entire svg. If I would add ```transform: translateY(-100px);``` to the keyframe, the svg moves up ```100px``` and not only the ```.lamp_fill class```. I am guessing there is a way to make only the target class move? So, to speak plainly, I would like to move only the ```.lamp_fill``` up 100px. – Johanna Jul 01 '22 at 12:37
  • @ccprog - thank you for checking the svg, how can I see the changes you made? – Johanna Jul 01 '22 at 12:40

1 Answers1

1

Currently, the are two objects with the class lamp-fill, and both get animated.

<div className={`animation_container ${visibleAnimation ? 'lamp_fill' : ''}`} >

and

<path className="lamp_fill" d="..." />

If you want only the second one to be animated, set the class only there. Like this:

<div
  ref={animationRef}
  className='animation_container'
>
  <svg
    viewBox="0 0 960 960"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <g id="lamp">
      <g id="_12">
        <g id="Group">
          <path
            className={visibleAnimation ? "lamp_fill" : ""}
            d="..."
          fill="black"
          />
          <!--multiple path elements-->
        </g>
      </g>
    </g>
  </svg>
ccprog
  • 20,308
  • 4
  • 27
  • 44