SVG Morphing in React JS with Anime JS
author

Jon Snow

25 April 2023

SVG Morphing in React JS with Anime JS


SVG Morphing in React JS with Anime JS

Output

SVG Morphing in React JS with Anime JS

There are many Javascript animation libraries out there, but Anime.js is one of the best. it's easy to use, has a small and simple API, and offers everything you could want from a modern animation engine. The library has a small file size and supports all modern browsers, including IE/Edge 11+.

Inspired by PAOLO DUZIONI

https://codepen.io/Paolo-Duzioni/pen/jvrxpLj

Gettling Started with Anime.js

npm install animejs

Make 2 files in Your React.js project

  1. AnimeJsExample.js
  2. AnimeJsExample.css

Import the anime from the animejs package

import anime from "animejs";

Write JSX Code

const AnimeJsExample = () => {
  
  return (
    <>
     <section id="my-section">
        <div className="active" id="wrap-cta">
          <button id="cta">Click here, please!</button>
        </div>
        <svg viewBox="0 0 215 110" preserveAspectRatio="none">
          <polygon className="polymorph" points="215,110 0,110 0,0 215,0" />
        </svg>
        <div className="container1">
          <div id="content">
            <h1>Lorem ipsum dolor sit amet</h1>
            <p>Dolor sit amet et consectquo lorem ipsum dolor sit amet</p>
            <button id="close">Ok, close me</button>
          </div>
        </div>
      </section>
    </>
  );
};


Import CSS File

import "./AnimeJsExample.css";

CSS Code

@import url("https://fonts.googleapis.com/css?family=Merriweather:400,400i,700");
/*  body {
	 font-family: Merriweather;
	 font-size: 16px;
} */
 #my-section {
	 position: relative;
}
 #wrap-cta {
	 position: absolute;
	 top: 50%;
	 left: 50%;
	 transform: translate(0, -50%);
	 opacity: 0;
}
 #wrap-cta.active {
	 z-index: 2;
	 transform: translate(-50%, -50%);
	 transition: transform 0.6s, opacity 0.6s;
	 opacity: 1;
}
 #wrap-cta #cta {
	 padding: 1rem 2rem;
	 text-transform: uppercase;
	 color: #f2f2f2;
	 background: transparent;
	 border: 2px solid;
	 border-radius: 5px;
	 cursor: pointer;
	 outline: none;
	 -webkit-tap-highlight-color: transparent;
	 transition: background 0.4s;
}
 #wrap-cta #cta:hover {
	 background: rgba(242, 242, 242, .1);
}
 svg {
	 display: block;
	 width: 100%;
	 height: 100vh;
}
 svg .polymorph {
	 fill: #b66c8d;
}
 .container1 {
	 position: absolute;
	 top: 50%;
	 left: 50%;
	 transform: translate(-50%, -50%);
	 text-align: center;
}
 .container1 #content {
	 transform: translateY(-50px);
	 opacity: 0;
	 color: #b66c8d;
	 transition: transform 0.6s 0.2s, opacity 0.6s 0.2s;
}
 .container1 #content #close {
	 display: inline-block;
	 margin-top: 2rem;
	 padding: 0.5rem 1rem;
	 text-transform: uppercase;
	 font-size: 0.9em;
	 color: #b66c8d;
	 background: transparent;
	 border: 2px solid;
	 border-radius: 5px;
	 cursor: pointer;
	 outline: none;
	 -webkit-tap-highlight-color: transparent;
	 transition: background 0.4s;
}
 .container1 #content #close:hover {
	 background: rgba(182, 108, 141, .3);
}
 .container1 #content.active {
	 z-index: 4;
	 transform: translateY(0);
	 opacity: 1;
}


We write all the animation code in useEffect so import the useEffect

import React, { useEffect } from "react";

Animation with anime js

 useEffect(() => {
   

    // Refs
    const wrapCta = document.querySelector("#wrap-cta"),
      btnCta = document.querySelector("#cta"),
      content = document.querySelector("#content"),
      btnClose = document.querySelector("#close");

    // Anime.js Commons Values for SVG Morph
    const common = {
      targets: ".polymorph",
      easing: "easeOutQuad",
      duration: 600,
      loop: false,
    };

    // Show content
    btnCta.addEventListener("click", () => {
      // Elements apparence
      wrapCta.classList.remove("active");
      content.classList.add("active");

      // Morph SVG
      anime({
        ...common,
        points: [{ value: "215,110 0,110 186,86 215,0" }],
      });
    });

    // Hide content
    btnClose.addEventListener("click", () => {
      // Elements apparence
      content.classList.remove("active");
      wrapCta.classList.add("active");

      // Morph SVG
      anime({
        ...common,
        points: [{ value: "215,110 0,110 0,0 215,0" }],
      });
    });
  }, []);

Full code of AnimeJsExample.js file

import React, { useEffect } from "react";
import anime from "animejs";
import "./AnimeJsExample.css";
const AnimeJsExample = () => {
    useEffect(() => {
   

    // Refs
    const wrapCta = document.querySelector("#wrap-cta"),
      btnCta = document.querySelector("#cta"),
      content = document.querySelector("#content"),
      btnClose = document.querySelector("#close");

    // Anime.js Commons Values for SVG Morph
    const common = {
      targets: ".polymorph",
      easing: "easeOutQuad",
      duration: 600,
      loop: false,
    };

    // Show content
    btnCta.addEventListener("click", () => {
      // Elements apparence
      wrapCta.classList.remove("active");
      content.classList.add("active");

      // Morph SVG
      anime({
        ...common,
        points: [{ value: "215,110 0,110 186,86 215,0" }],
      });
    });

    // Hide content
    btnClose.addEventListener("click", () => {
      // Elements apparence
      content.classList.remove("active");
      wrapCta.classList.add("active");

      // Morph SVG
      anime({
        ...common,
        points: [{ value: "215,110 0,110 0,0 215,0" }],
      });
    });
  }, []);
   
   return (
    <>
     <section id="my-section">
        <div className="active" id="wrap-cta">
          <button id="cta">Click here, please!</button>
        </div>
        <svg viewBox="0 0 215 110" preserveAspectRatio="none">
          <polygon className="polymorph" points="215,110 0,110 0,0 215,0" />
        </svg>
        <div className="container1">
          <div id="content">
            <h1>Lorem ipsum dolor sit amet</h1>
            <p>Dolor sit amet et consectquo lorem ipsum dolor sit amet</p>
            <button id="close">Ok, close me</button>
          </div>
        </div>
      </section>
    </>
  );
};

export default AnimeJsExample;

Thank You 🧡🧡


Share:  
https://www.democoding.in/blog...

Related Post

programming meme
Code Snippet

Codepen Ideas