Home > Mobile >  Transition between two SVG react
Transition between two SVG react

Time:09-06

I have a header with Logo, on left side, page title - in the middle, and user menu, on the right. Currently I'm displaying a SVG next to each page title. For example, on page /organizations I display this:

enter image description here

After that I've added a SVG that shows when I hover on the element (it's the same SVG, but filled)

enter image description here

How could I make transition between these two smooth? I'm using Tailwind for styling and tried adding transition-all to almost every class but that sadly didn't work.

This is the code responsible for switching between the SVGs:

 const [hover, setHover] = React.useState(false);

 const handleMouseOver = () => {
    setHover(true);
 };
 const handleMouseLeave = () => {
    setHover(false);
 };

return (
...
   <div className="w-1/2 flex justify-center">
      <Link
        to={getModuleInfo(pathname, t, organization).url}
        className="max-w-fit flex items-center gap-2"
        prefetch="intent"
      >
        <div
          className="flex items-center gap-2"
          onm ouseOver={handleMouseOver}
          onm ouseLeave={handleMouseLeave}
        >
          <>
             {hover
              ? getModuleInfo(pathname, t, organization).logoHover
              : getModuleInfo(pathname, t, organization).logo}
          </>
          <h5 className="organizations text-md md:text-2xl font-sans font-normal text-center text-colublue-500">
            {getModuleInfo(pathname, t, organization).title}
          </h5>
        </div>
      </Link>
    </div>
...
)

UPD: to make things more clear, these would be 2 SVG examples that I would like to transition between:

enter image description here

And this are the <svg> for them:

// Unfilled SVG
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.41421 2.58579C8.78929 2.21071 9.29799 2 9.82843 2H18C18.5304 2 19.0391 2.21071 19.4142 2.58579C19.7893 2.96086 20 3.46957 20 4V20C20 20.5304 19.7893 21.0391 19.4142 21.4142C19.0391 21.7893 18.5304 22 18 22H6C5.46957 22 4.96086 21.7893 4.58579 21.4142C4.21071 21.0391 4 20.5304 4 20V7.82843C4 7.29799 4.21071 6.78929 4.58579 6.41421L8.41421 2.58579Z" stroke="#052141" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10 2V7C10 7.55228 9.55228 8 9 8H4.5" stroke="#052141" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>


// Filled SVG
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.82843 1C9.03278 1 8.26972 1.31607 7.70711 1.87868L3.87868 5.70711C3.31607 6.26972 3 7.03278 3 7.82843V20C3 20.7957 3.31607 21.5587 3.87868 22.1213C4.44129 22.6839 5.20435 23 6 23H18C18.7956 23 19.5587 22.6839 20.1213 22.1213C20.6839 21.5587 21 20.7957 21 20V4C21 3.20435 20.6839 2.44129 20.1213 1.87868C19.5587 1.31607 18.7956 1 18 1H9.82843ZM16.7071 9.29289C17.0976 9.68342 17.0976 10.3166 16.7071 10.7071L11.3738 16.0404C10.9832 16.431 10.3501 16.431 9.95956 16.0404L7.29289 13.3738C6.90237 12.9832 6.90237 12.3501 7.29289 11.9596C7.68342 11.569 8.31658 11.569 8.70711 11.9596L10.6667 13.9191L15.2929 9.29289C15.6834 8.90237 16.3166 8.90237 16.7071 9.29289Z" fill="#052141"/>
</svg>

CodePudding user response:

With plain CSS and SVG, you can do this with opacity and transition.

.filled {
  opacity: 0;
  transition: opacity 0.3s;
}

svg:hover .filled {
  opacity: 1;
}
<svg width="96" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path d="M8.41421 2.58579C8.78929 2.21071 9.29799 2 9.82843 2H18C18.5304 2 19.0391 2.21071 19.4142 2.58579C19.7893 2.96086 20 3.46957 20 4V20C20 20.5304 19.7893 21.0391 19.4142 21.4142C19.0391 21.7893 18.5304 22 18 22H6C5.46957 22 4.96086 21.7893 4.58579 21.4142C4.21071 21.0391 4 20.5304 4 20V7.82843C4 7.29799 4.21071 6.78929 4.58579 6.41421L8.41421 2.58579Z" stroke="#052141" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
  <path d="M10 2V7C10 7.55228 9.55228 8 9 8H4.5" stroke="#052141" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
  <path  d="M9.82843 1C9.03278 1 8.26972 1.31607 7.70711 1.87868L3.87868 5.70711C3.31607 6.26972 3 7.03278 3 7.82843V20C3 20.7957 3.31607 21.5587 3.87868 22.1213C4.44129 22.6839 5.20435 23 6 23H18C18.7956 23 19.5587 22.6839 20.1213 22.1213C20.6839 21.5587 21 20.7957 21 20V4C21 3.20435 20.6839 2.44129 20.1213 1.87868C19.5587 1.31607 18.7956 1 18 1H9.82843ZM16.7071 9.29289C17.0976 9.68342 17.0976 10.3166 16.7071 10.7071L11.3738 16.0404C10.9832 16.431 10.3501 16.431 9.95956 16.0404L7.29289 13.3738C6.90237 12.9832 6.90237 12.3501 7.29289 11.9596C7.68342 11.569 8.31658 11.569 8.70711 11.9596L10.6667 13.9191L15.2929 9.29289C15.6834 8.90237 16.3166 8.90237 16.7071 9.29289Z" fill="#052141"/>
</svg>

CodePudding user response:

You could also use css variables to transition between the design states.

Similar to @ksav's this approach will also need to combine both svgs.
This way we can render the icon with more design variations.

let icon = document.querySelector('.iconTrans');

function toggleState() {
  icon.classList.toggle('active')
}
svg {
  border: 1px solid #ccc;
  overflow: visible;
  width: 10em;
}

svg path {
  transition: 1s;
}

.iconTrans {
  --strokeColor: #052141;
  --strokeWidth: 2px;
  --opacity1: 1;
  --opacity2: 0;
  --fillColor: #052141;
}

.active {
  --strokeColor: #052141;
  --strokeWidth: 0px;
  --opacity1: 0;
  --opacity2: 1;
  --fillColor: #ccc;
}
<p><button id="btnToggle" onclick="toggleState()">Toggle state</button></p>
<svg  viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path  d="M8.41421 2.58579C8.78929 2.21071 9.29799 2 9.82843 2H18C18.5304 2 19.0391 2.21071 19.4142 2.58579C19.7893 2.96086 20 3.46957 20 4V20C20 20.5304 19.7893 21.0391 19.4142 21.4142C19.0391 21.7893 18.5304 22 18 22H6C5.46957 22 4.96086 21.7893 4.58579 21.4142C4.21071 21.0391 4 20.5304 4 20V7.82843C4 7.29799 4.21071 6.78929 4.58579 6.41421L8.41421 2.58579Z 
M10 2V7C10 7.55228 9.55228 8 9 8H4.5" style="stroke:var(--strokeColor); stroke-width:var(--strokeWidth); opacity:var(--opacity1)" stroke-linecap="round" stroke-linejoin="round" />
  <path  d="M9.82843 1C9.03278 1 8.26972 1.31607 7.70711 1.87868L3.87868 5.70711C3.31607 6.26972 3 7.03278 3 7.82843V20C3 20.7957 3.31607 21.5587 3.87868 22.1213C4.44129 22.6839 5.20435 23 6 23H18C18.7956 23 19.5587 22.6839 20.1213 22.1213C20.6839 21.5587 21 20.7957 21 20V4C21 3.20435 20.6839 2.44129 20.1213 1.87868C19.5587 1.31607 18.7956 1 18 1H9.82843Z
M16.7071 9.29289C17.0976 9.68342 17.0976 10.3166 16.7071 10.7071L11.3738 16.0404C10.9832 16.431 10.3501 16.431 9.95956 16.0404L7.29289 13.3738C6.90237 12.9832 6.90237 12.3501 7.29289 11.9596C7.68342 11.569 8.31658 11.569 8.70711 11.9596L10.6667 13.9191L15.2929 9.29289C15.6834 8.90237 16.3166 8.90237 16.7071 9.29289Z" style="fill:var(--fillColor); opacity:var(--opacity2); " />
</svg>

  • Related