Home > Back-end >  IntersectionObserver - transform properties targets the whole SVG animation and not class
IntersectionObserver - transform properties targets the whole SVG animation and not class

Time:07-07

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

CodePudding user response:

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>
  • Related