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