简体   繁体   中英

How to convert animated SVG to a React functional component

I am trying to take an SVG that I downloaded from LOADING.io and convert it to a React functional component. I tried using react-svgr.com to convert the SVG but the animation doesn't render, just a static icon.

I also tried to simply insert the SVG into my react component, but there are so many errors. I have no clue as to what to do to get this working. I don't want to use the link for the SVG, I want to serve it to the client.

import React from 'react';

const Spinner = (props) => {
  return (
    <svg
      xmlSpace="preserve"
      viewBox="0 0 100 100"
      y={0}
      x={0}
      id="prefix__Layer_1"
      style={{
        height: '100%',
        width: '100%',
        background: '0 0'
      }}
      width={199}
      height={199}
      shapeRendering="auto"
      {...props}
    >
      <g
        className="prefix__ldl-scale"
        style={{
          transformOrigin: '50% 50%'
        }}
      >
        <g className="prefix__ldl-ani">
          <g className="prefix__ldl-layer">
            <path
              d="M21.666 44.118L5 37.431V12.569l16.666 6.687z"
              strokeMiterlimit={10}
              strokeLinejoin="round"
              strokeWidth={1.75}
              stroke="#323232"
              fill="#f7b26a"
            />
          </g>
          <g className="prefix__ldl-layer">
            <path
              d="M14.99 37.44l-6.218-2.495"
              strokeMiterlimit={10}
              strokeLinecap="round"
              strokeWidth={1.75}
              stroke="#323232"
              fill="#f7b26a"
              strokeLinejoin="round"
            />
          </g>
          <g className="prefix__ldl-layer">
            <path
              d="M12.937 33.116l-4.165-1.671"
              strokeMiterlimit={10}
              strokeLinecap="round"
              strokeWidth={1.75}
              stroke="#323232"
              fill="#f7b26a"
              strokeLinejoin="round"
            />
          </g>
          <g className="prefix__ldl-layer">
            <path
              d="M21.666 44.118L45 37.431V12.569l-23.334 6.687z"
              strokeMiterlimit={10}
              strokeLinejoin="round"
              strokeWidth={1.75}
              stroke="#323232"
              fill="#f7b26a"
            />
          </g>
          <g className="prefix__ldl-layer">
            <path
              d="M45 12.569L28.334 5.882 5 12.569h0l16.666 6.687L45 12.569z"
              strokeMiterlimit={10}
              strokeLinejoin="round"
              strokeWidth={1.75}
              stroke="#323232"
              fill="#f7b26a"
            />
          </g>
          <g className="prefix__ldl-layer">
            <path
              d="M20.34 8.172l-6.592 1.89 16.666 6.687 6.592-1.889z"
              strokeLinejoin="round"
              stroke="#323232"
              fill="#f4e6c8"
              strokeMiterlimit={10}
              strokeWidth={1.75}
            />
          </g>
          <g className="prefix__ldl-layer">
            <path
              d="M37.006 21.032l-6.593 1.89v-6.173l6.593-1.889z"
              strokeLinejoin="round"
              stroke="#323232"
              fill="#f4e6c8"
              strokeMiterlimit={10}
              strokeWidth={1.75}
            />
          </g>
          <g className="prefix__ldl-layer">
            <path
              d="M27.492 42.449L45 37.43V12.569l-7.886 2.26z"
              strokeLinejoin="round"
              stroke="#000"
              opacity={0.2}
              strokeMiterlimit={10}
              strokeWidth={1.75}
            />
          </g>
          <g className="prefix__ldl-layer">
            <path
              d="M37.069 14.842L45 12.569h0l-7.931-3.183z"
              strokeLinejoin="round"
              stroke="#000"
              opacity={0.2}
              strokeMiterlimit={10}
              strokeWidth={1.75}
            />
          </g>
        </g>
      </g>
      <style id="tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e">
        {
          '@keyframes tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e{0%{transform:translate(0,0) rotate(0deg) scale(1)}3.33333%{transform:translate(-.18923px,1.45485px) rotate(0deg) scale(1)}6.66667%{transform:translate(-.84296px,-1.32524px) rotate(0deg) scale(1)}10%{transform:translate(.67971px,1.00422px) rotate(0deg) scale(1)}13.33333%{transform:translate(-.5056px,.83616px) rotate(0deg) scale(1)}16.66667%{transform:translate(1.31368px,-.51401px) rotate(0deg) scale(1)}20%{transform:translate(-1.21184px,1.49193px) rotate(0deg) scale(1)}23.33333%{transform:translate(1.09065px,-.21259px) rotate(0deg) scale(1)}26.66667%{transform:translate(-1.49916px,.56159px) rotate(0deg) scale(1)}30%{transform:translate(1.48086px,1.21228px) rotate(0deg) scale(1)}33.33333%{transform:translate(-1.43889px,-1.152px) rotate(0deg) scale(1)}36.66667%{transform:translate(1.35914px,1.34835px) rotate(0deg) scale(1)}40%{transform:translate(-1.42834px,.3091px) rotate(0deg) scale(1)}43.33333%{transform:translate(1.47472px,-1.49889px) rotate(0deg) scale(1)}46.66667%{transform:translate(-.92402px,1.4416px) rotate(0deg) scale(1)}50%{transform:translate(1.0657px,-.75306px) rotate(0deg) scale(1)}53.33333%{transform:translate(-1.19035px,-1.07484px) rotate(0deg) scale(1)}56.66667%{transform:translate(.28828px,.79337px) rotate(0deg) scale(1)}60%{transform:translate(-.47167px,-1.42789px) rotate(0deg) scale(1)}63.33333%{transform:translate(.64753px,-.09795px) rotate(0deg) scale(1)}66.66667%{transform:translate(.41006px,-.26292px) rotate(0deg) scale(1)}70%{transform:translate(-.22477px,-1.3683px) rotate(0deg) scale(1)}73.33333%{transform:translate(.03588px,.92931px) rotate(0deg) scale(1)}76.66667%{transform:translate(-1.01937px,-1.18398px) rotate(0deg) scale(1)}80%{transform:translate(.8724px,-.60494px) rotate(0deg) scale(1)}83.33333%{transform:translate(-.71151px,1.4786px) rotate(0deg) scale(1)}86.66667%{transform:translate(1.40734px,-1.49607px) rotate(0deg) scale(1)}90%{transform:translate(-1.33062px,.46957px) rotate(0deg) scale(1)}93.33333%{transform:translate(1.23264px,1.26738px) rotate(0deg) scale(1)}96.66667%{transform:translate(-1.48975px,-1.03867px) rotate(0deg) scale(1)}to{transform:translate(0,0) rotate(0) scale(1)}}'
        }
      </style>
    </svg>
  );
};
export default Spinner;

Original SVG:

<?xml version="1.0" encoding="utf-8"?>
<svg xml:space="preserve" viewBox="0 0 100 100" y="0" x="0" xmlns="http://www.w3.org/2000/svg" id="Layer_1" version="1.1" style="height: 100%; width: 100%; background: none; shape-rendering: auto;" width="104px" height="104px">
  <g class="ldl-scale" style="transform-origin: 50% 50%; transform: rotate(0deg) scale(0.5, 0.5);">
    <g class="ldl-ani">
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -0.725926s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M43.331 88.236L10 74.862V25.138l33.331 13.374z" stroke-miterlimit="10" stroke-linejoin="round" stroke-width="3.5" stroke="#323232" fill="#f7b26a" style="fill: rgb(247, 178, 106); stroke: rgb(50, 50, 50);"></path>
        </g>
      </g>
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -0.774074s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M29.981 74.88l-12.437-4.991" stroke-miterlimit="10" stroke-linecap="round" stroke-width="3.5" stroke="#323232" fill="#f7b26a" stroke-linejoin="round" style="fill: rgb(247, 178, 106); stroke: rgb(50, 50, 50);"></path>
        </g>
      </g>
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -0.822222s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M25.874 66.232l-8.33-3.343" stroke-miterlimit="10" stroke-linecap="round" stroke-width="3.5" stroke="#323232" fill="#f7b26a" stroke-linejoin="round" style="fill: rgb(247, 178, 106); stroke: rgb(50, 50, 50);"></path>
        </g>
      </g>
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -0.87037s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M43.331 88.236L90 74.862V25.138L43.331 38.512z" stroke-miterlimit="10" stroke-linejoin="round" stroke-width="3.5" stroke="#323232" fill="#f7b26a" style="fill: rgb(247, 178, 106); stroke: rgb(50, 50, 50);"></path>
        </g>
      </g>
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -0.918519s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M90 25.138L56.669 11.764 10 25.138h0l33.331 13.374L90 25.138z" stroke-miterlimit="10" stroke-linejoin="round" stroke-width="3.5" stroke="#323232" fill="#f7b26a" style="fill: rgb(247, 178, 106); stroke: rgb(50, 50, 50);"></path>
        </g>
      </g>
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -0.966667s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M40.681 16.345l-13.185 3.779 33.331 13.374 13.185-3.778z" stroke-linejoin="round" stroke="#323232" fill="#f4e6c8" stroke-miterlimit="10" stroke-width="3.5" style="fill: rgb(244, 230, 200); stroke: rgb(50, 50, 50);"></path>
        </g>
      </g>
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -1.01481s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M74.012 42.065l-13.185 3.778V33.498l13.185-3.778z" stroke-linejoin="round" stroke="#323232" fill="#f4e6c8" stroke-miterlimit="10" stroke-width="3.5" style="fill: rgb(244, 230, 200); stroke: rgb(50, 50, 50);"></path>
        </g>
      </g>
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -1.06296s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M54.984 84.897L90 74.862V25.138l-15.773 4.52z" stroke-linejoin="round" stroke="#000" opacity=".2" stroke-miterlimit="10" stroke-width="3.5" style="fill: rgb(0, 0, 0); stroke: rgb(0, 0, 0);"></path>
        </g>
      </g>
      <g class="ldl-layer">
        <g class="ldl-ani" style="transform: matrix(1, 0, 0, 1, 0, 0); transform-origin: 50px 50px; animation: 1.11111s linear -1.11111s infinite normal forwards running tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e;">
          <path d="M74.137 29.684L90 25.138h0l-15.863-6.365z" stroke-linejoin="round" stroke="#000" opacity=".2" stroke-miterlimit="10" stroke-width="3.5" style="fill: rgb(0, 0, 0); stroke: rgb(0, 0, 0);"></path>
        </g>
      </g>
      <metadata xmlns:d="https://loading.io/stock/">
        <d:name>box</d:name>
        <d:tags>box,carton,carboard boxes,container,package,payload,express,delivery,mail,goods</d:tags>
        <d:license>by</d:license>
        <d:slug>gkonp9</d:slug>
      </metadata>
    </g>
  </g>
  <style id="tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e" data-anikit="">
    @keyframes tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e {
      0% {
        transform: translate(0px,0px) rotate(0deg) scale(1);
      }
      3.33333% {
        transform: translate(-0.18923px,1.45485px) rotate(0deg) scale(1);
      }
      6.66667% {
        transform: translate(-0.84296px,-1.32524px) rotate(0deg) scale(1);
      }
      10% {
        transform: translate(0.67971px,1.00422px) rotate(0deg) scale(1);
      }
      13.33333% {
        transform: translate(-0.5056px,0.83616px) rotate(0deg) scale(1);
      }
      16.66667% {
        transform: translate(1.31368px,-0.51401px) rotate(0deg) scale(1);
      }
      20% {
        transform: translate(-1.21184px,1.49193px) rotate(0deg) scale(1);
      }
      23.33333% {
        transform: translate(1.09065px,-0.21259px) rotate(0deg) scale(1);
      }
      26.66667% {
        transform: translate(-1.49916px,0.56159px) rotate(0deg) scale(1);
      }
      30% {
        transform: translate(1.48086px,1.21228px) rotate(0deg) scale(1);
      }
      33.33333% {
        transform: translate(-1.43889px,-1.152px) rotate(0deg) scale(1);
      }
      36.66667% {
        transform: translate(1.35914px,1.34835px) rotate(0deg) scale(1);
      }
      40% {
        transform: translate(-1.42834px,0.3091px) rotate(0deg) scale(1);
      }
      43.33333% {
        transform: translate(1.47472px,-1.49889px) rotate(0deg) scale(1);
      }
      46.66667% {
        transform: translate(-0.92402px,1.4416px) rotate(0deg) scale(1);
      }
      50% {
        transform: translate(1.0657px,-0.75306px) rotate(0deg) scale(1);
      }
      53.33333% {
        transform: translate(-1.19035px,-1.07484px) rotate(0deg) scale(1);
      }
      56.66667% {
        transform: translate(0.28828px,0.79337px) rotate(0deg) scale(1);
      }
      60% {
        transform: translate(-0.47167px,-1.42789px) rotate(0deg) scale(1);
      }
      63.33333% {
        transform: translate(0.64753px,-0.09795px) rotate(0deg) scale(1);
      }
      66.66667% {
        transform: translate(0.41006px,-0.26292px) rotate(0deg) scale(1);
      }
      70% {
        transform: translate(-0.22477px,-1.3683px) rotate(0deg) scale(1);
      }
      73.33333% {
        transform: translate(0.03588px,0.92931px) rotate(0deg) scale(1);
      }
      76.66667% {
        transform: translate(-1.01937px,-1.18398px) rotate(0deg) scale(1);
      }
      80% {
        transform: translate(0.8724px,-0.60494px) rotate(0deg) scale(1);
      }
      83.33333% {
        transform: translate(-0.71151px,1.4786px) rotate(0deg) scale(1);
      }
      86.66667% {
        transform: translate(1.40734px,-1.49607px) rotate(0deg) scale(1);
      }
      90% {
        transform: translate(-1.33062px,0.46957px) rotate(0deg) scale(1);
      }
      93.33333% {
        transform: translate(1.23264px,1.26738px) rotate(0deg) scale(1);
      }
      96.66667% {
        transform: translate(-1.48975px,-1.03867px) rotate(0deg) scale(1);
      }
      100% {
        transform: translate(0,0) rotate(0) scale(1);
      }
    }
  </style>
  <!-- [ldio] generated by https://loading.io/ -->
</svg>

The animation should be applied as a class to the svg element. So in this case, a solution would be to assign the keyframe that is included in the style tag to a class and assign that class to the svg tag.

  1. Add the following to your style tag's content
.tremble-svg {
    animation: tremble-4fb58719-5a99-424e-9f7a-9ad2dd9d968e 1s infinite;
}
  1. Add a new class to the svg tag
<svg
  xmlSpace="preserve"
  viewBox="0 0 100 100"
  ...
  className="tremble-svg" // add this
/>
...
</svg>
    

And you should see the tremble animation playing for 1 second duration infinitely.

During the import process, is running. It removes unknown inline styles during its attempt to convert all styles to attributes. This is a clear bug. (But don't let me start about the shortcommings of this lib...)

You can alleviate this by setting "convertStyleToAttrs": false in the SVGO plugin config in webpack. In the svgr.com playground for example, you would choose SVGO > config and set it to

{ "plugins": [{ "removeTitle": false, "convertStyleToAttrs": false,  "removeViewBox": false }] }

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