Jump to content
Search Community

MorphSVG and React Help

blumaa@gmail.com test
Moderator Tag

Recommended Posts

Hello,

 

I'm trying to figure out how to use MorphSVG with React. When I do a gsap.from(start, 2, {x:400}) for a regular animation, everything works fine. But when I try to morph the square into the start, nothing happens. Any help is appreciated! I should mention that I have installed the club GreenSock packages correctly. This is what my component looks like:

 

import React, { useRef, useEffect } from "react";
import gsap, { TweenMax, Power4 } from "gsap";
import MorphSVGPlugin from "gsap/MorphSVGPlugin";

gsap.registerPlugin(MorphSVGPlugin);

const MorphShape = () => {

  let start = useRef(null);
  let end = useRef(null);

  console.log("start", start);

  useEffect(() => {
    console.log("start", start);
    console.log("end", end);

    // gsap.from(start, 3, {x: 400})
    gsap.to(start, {duration: 1, morphSVG:end});
  });

  return (
    <>
      <svg
        id="Layer_1"
        data-name="Layer 1"
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 1125 1125"
      >
        <title>developer</title>
        <rect
          id="start"
          width="1125"
          height="1125"
          fill="#a39274"
          ref={(el) => (start = el)}
        />
        <polygon
          id="end"
          points="562.5 71.54 689.62 439.36 1078.72 446.6 768.19 681.16 881.54 1053.46 562.5 830.61 243.46 1053.46 356.81 681.16 46.28 446.6 435.38 439.36 562.5 71.54"
          fill="none"
          stroke="#515151"
          stroke-miterlimit="10"
          stroke-width="18"
          ref={(el) => (end = el)}
        />
      </svg>
    </>
  );
};

export default MorphShape;

 

Link to comment
Share on other sites

TweenMax is deprecated. Just use gsap. 

https://greensock.com/docs/v3/Installation

 

So are ease objects. Just use strings now.

// braces allow for autocomplete in editor
import { gsap } from "gsap";
import { MorphSVGPlugin } from "gsap/MorphSVGPlugin";

gsap.to(el, {
  x: 300,
  ease: "power4.out"
});

 

You need to convert your shapes to path elements.

https://greensock.com/docs/v3/Plugins/MorphSVGPlugin/static.convertToPath()

 

That's probably going to mess up your refs. You should probably convert it to paths before instead of at runtime.

 

  • Like 4
Link to comment
Share on other sites

I'd just did it in codepen by copying the svg from the dev console. I put the shape you want to morph to inside <defs> so that it doesn't get rendered.

 

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1125 1125">
<title>developer</title>
<defs>
<path stroke-width="18" stroke-miterlimit="10" stroke="#515151" fill="none" id="end" d="M562.5,71.54 C604.87333,194.14667 647.24667,316.75333 689.62,439.36 819.32,441.77333 949.02,444.18667 1078.72,446.6 975.21,524.78667 871.7,602.97333 768.19,681.16 805.97333,805.26 843.75667,929.36 881.54,1053.46 775.19333,979.17667 668.84667,904.89333 562.5,830.61 456.15333,904.89333 349.80667,979.17667 243.46,1053.46 281.24333,929.36 319.02667,805.26 356.81,681.16 253.3,602.97333 149.79,524.78667 46.28,446.6 175.98,444.18667 305.68,441.77333 435.38,439.36 477.75333,316.75333 520.12667,194.14667 562.5,71.54 562.5,71.54 562.5,71.54 562.5,71.54 z"></path>
</defs>
<path fill="#a39274" id="start" d="M1125,0 C1125,375 1125,750 1125,1125 750,1125 375,1125 0,1125 0,750 0,375 0,0 375,0 750,0 1125,0 z"></path>
</svg>

 

See the Pen 2243ed330620e43e78aaf2089cf22610 by osublake (@osublake) on CodePen

 

  • Like 2
Link to comment
Share on other sites

Yes. That part makes sense. I should clarify that I can make this all work in codepen. It's when I try it in the react environment that things get tricky. I guess I'm not sure how to convert the svg to path while I use refs for each of the polygon and rect nodes. As in what I'm doing in my screenshot above.

 

Thanks!

Link to comment
Share on other sites

That's the whole point. Don't do it at runtime. Do the processing before hand.

 

Just copy and paste this into your app.

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1125 1125">
<title>developer</title>
<defs>
<path ref={end} stroke-width="18" stroke-miterlimit="10" stroke="#515151" fill="none" id="end" d="M562.5,71.54 C604.87333,194.14667 647.24667,316.75333 689.62,439.36 819.32,441.77333 949.02,444.18667 1078.72,446.6 975.21,524.78667 871.7,602.97333 768.19,681.16 805.97333,805.26 843.75667,929.36 881.54,1053.46 775.19333,979.17667 668.84667,904.89333 562.5,830.61 456.15333,904.89333 349.80667,979.17667 243.46,1053.46 281.24333,929.36 319.02667,805.26 356.81,681.16 253.3,602.97333 149.79,524.78667 46.28,446.6 175.98,444.18667 305.68,441.77333 435.38,439.36 477.75333,316.75333 520.12667,194.14667 562.5,71.54 562.5,71.54 562.5,71.54 562.5,71.54 z"></path>
</defs>
<path ref={start} fill="#a39274" id="start" d="M1125,0 C1125,375 1125,750 1125,1125 750,1125 375,1125 0,1125 0,750 0,375 0,0 375,0 750,0 1125,0 z"></path>
</svg>

 

Link to comment
Share on other sites

This should work.

 

const MorphShape = () => {

  let start = useRef(null);
  let end = useRef(null);

  console.log("start", start);

  useEffect(() => {
    console.log("start", start);
    console.log("end", end);

    gsap.to(start, {duration: 1, morphSVG:end});
  }, []);

  return (
    <>
      <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1125 1125">
    <title>developer</title>
    <defs>
    <path ref={end} stroke-width="18" stroke-miterlimit="10" stroke="#515151" fill="none" id="end" d="M562.5,71.54 C604.87333,194.14667 647.24667,316.75333 689.62,439.36 819.32,441.77333 949.02,444.18667 1078.72,446.6 975.21,524.78667 871.7,602.97333 768.19,681.16 805.97333,805.26 843.75667,929.36 881.54,1053.46 775.19333,979.17667 668.84667,904.89333 562.5,830.61 456.15333,904.89333 349.80667,979.17667 243.46,1053.46 281.24333,929.36 319.02667,805.26 356.81,681.16 253.3,602.97333 149.79,524.78667 46.28,446.6 175.98,444.18667 305.68,441.77333 435.38,439.36 477.75333,316.75333 520.12667,194.14667 562.5,71.54 562.5,71.54 562.5,71.54 562.5,71.54 z"></path>
</defs>
<path ref={start} fill="#a39274" id="start" d="M1125,0 C1125,375 1125,750 1125,1125 750,1125 375,1125 0,1125 0,750 0,375 0,0 375,0 750,0 1125,0 z"></path>
</svg>
    </>
  );
};

 

  • Like 3
Link to comment
Share on other sites

Yes! Thank you! It is working.

 

So basically I just need to convert all shapes in codepen and then copy them into my react component, then add the refs..

 

I made a slight modification for the ref to make it work. I'll post the code here.

import React, { useRef, useEffect } from "react";
import { gsap } from "gsap";
import { MorphSVGPlugin } from "gsap/MorphSVGPlugin";

gsap.registerPlugin(MorphSVGPlugin);

const MorphLetters = () => {
  let start = useRef(null);
  let end = useRef(null);

  console.log("start", start);

  useEffect(() => {
    console.log("start", start);
    console.log("end", end);
    gsap.to(start, {duration: 1, morphSVG:end});

  });

  return (
    <>
      <svg
        id="Layer_1"
        data-name="Layer 1"
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 1125 1125"
      >
        <title>developer</title>
        <defs>
          <path
            ref={el=> end = el}
            stroke-width="18"
            stroke-miterlimit="10"
            stroke="#515151"
            fill="none"
            id="end"
            d="M562.5,71.54 C604.87333,194.14667 647.24667,316.75333 689.62,439.36 819.32,441.77333 949.02,444.18667 1078.72,446.6 975.21,524.78667 871.7,602.97333 768.19,681.16 805.97333,805.26 843.75667,929.36 881.54,1053.46 775.19333,979.17667 668.84667,904.89333 562.5,830.61 456.15333,904.89333 349.80667,979.17667 243.46,1053.46 281.24333,929.36 319.02667,805.26 356.81,681.16 253.3,602.97333 149.79,524.78667 46.28,446.6 175.98,444.18667 305.68,441.77333 435.38,439.36 477.75333,316.75333 520.12667,194.14667 562.5,71.54 562.5,71.54 562.5,71.54 562.5,71.54 z"
          ></path>
        </defs>
        <path
          ref={el=>start=el}
          fill="#a39274"
          id="start"
          d="M1125,0 C1125,375 1125,750 1125,1125 750,1125 375,1125 0,1125 0,750 0,375 0,0 375,0 750,0 1125,0 z"
        ></path>
      </svg>
    </>
  );
};

export default MorphLetters;

I very much appreciate it.

  • Thanks 1
Link to comment
Share on other sites

3 minutes ago, blumaa@gmail.com said:

I made a slight modification for the ref to make it work. I'll post the code here.

 

Oh, that's because I forgot to include current.

useEffect(() => {

  gsap.to(start.current, { duration: 1, morphSVG: end.current });
  
}, []); // !!! Notice the array. That makes sure it only runs once

 

3 minutes ago, blumaa@gmail.com said:

So basically I just need to convert all shapes in codepen and then copy them into my react component, then add the refs..

 

That's what I would do. 😉

 

 

  • Like 4
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...