简体   繁体   中英

How to use animated svg in react functional component?

i want to add animation to svg using react.

what i am trying to do? i have an animation svg like below code,

<svg id="something">
    <g>
        <path>
        <script>
            //some script
        </script>
    </svg>

i have used this code in a functional component like below,

function AnimatedIcon() {
    return (
        <svg>
            <g>
                <path>
            </g>
            <script>
                //some script
           </script>
       </svg>

but this gives me an error unexpected token.

I am not sure why it is giving that error.

how can i move this script to a function on render. could someone help me with this. thanks.

i am new to react and animations. could someone help me with this. thanks.

Looks like you are missing a closing tag for path.

<svg>
  <path/>
  <g>{/* <path> */}</g>     
  <script>//some script</script>
</svg>

Ciao, seems that you are not closing tag <path> . Try to modify your code like this:

    <svg>
      <g>
        <path />
      </g>
      <script>{/*some script */}</script>
    </svg>

Anyway, I think you are focused on how to animate an svg in React. Here a working example. Lets say you have this svg and you want to animate it.

At first we see Samy tag from react-samy-svg . It's just a library to better manage svg in React.

Then, next tag is Animate tag from react-move . This is the tag we use to animate our image. In my example, this tag has 2 props:

  1. start : A function that returns the starting state. The function is passed the data and index and must return an object.
  2. update : A function that returns an object or array of objects describing how the state should transform on update. The function is passed the data and index.

So, as you can see in my example, element inside start prop is setted to 0:

start={() => ({
   y: 0
})}

Instead, update element is setted with a state variables (so that means that it will change somewhere):

update={() => ({
   y: bodyY
})}

And now the magic: inside Animate tag we define, for each part of robot image that we want to animate, an SvgProxy tag. With selector prop we get html element that we want to aniamte and with transform prop we apply a move to that htlm element (and his children of course).

So for example, if we want to move robot body (that has html id="core"), we write something like this:

<SvgProxy
   selector="#core"  //select body
   transform={`translate(0 ${data.y})`} //move body with css translate
/>

Yes but who sets data.y to make this translation? Lets see useEffect hooks. Inside we found a setInterval function like this:

setInterval(() => {
    let result = jump();
    setbodyY(result.bodyY);
 }, 500);

That means that, each 500ms setInterval calls setbodyY , so each 500ms setInterval sets component's state. What is jump ? Is a function that returns a value to store into state.

const jump = () => {
   return { bodyY: Math.random() * 10 - 10 };
};

As you can see, jump returns a random value for bodyY . And if you go back on update props of Animate tag you see:

y: bodyY,

So in a few words, this means: "each 500ms set robot body y coords to value Math.random() * 10 - 10".

Same explanation is valid for arm1 and arm2 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM