Search code examples
reactjsanimationsvggsap

How to animate a transition between two SVG paths using GSAP


In one of my previous question I asked how it could be done to animate the transition between two svg paths. I understand that to use the animated tag is too complex in my case because I have paths very complex and “unpredictable”.

I found the library gsap that I am sure will help me. Here is the code I'm using:

import React from 'react'
import gsap, { TweenMax, Power2 } from 'gsap'

// example paths
const start =
  'M504,218.03470723826067L486.6401970759167,217.05546168413645L467.9061726178867,214.20181212746178L452.2919661559008,209.88866925502964L439.71877802832967,204.52551901017495L429.63706311342685,198.43728078766293L421.45022268399384,191.851556622786L414.66570643504747,184.9209283798573L408.91256568061823,177.747337873903L403.91895428364114,170.40001589195526L399.4852849887268,162.92722634676034L395.46246292998484,155.36371246933945L391.7360015272425,147.7354305648741L388.2147391955615,140.06262612082855L384.82273453267896,132.36190935249988L381.4932069605524,124.6477375137062L378.1636793884258,116.93356567491251L374.7716747255433,109.23284890658385L371.25041239386235,101.56004446253831L367.52395099112,93.93176255807295L363.50112893237804,86.36824868065204L359.06745963746374,78.89545913545712L354.0738482404867,71.54813715350937L348.32070748605753,64.37454664755509L341.5361912371112,57.443918404626345L333.34935080767843,50.858194239749366L323.26763589277573,44.76995601723728L310.69444776520476,39.406805772382526L295.08024130321934,35.09366289995029L276.34621684518925,32.240013343275464L255.49320696055227,31.233140225249358L234.64019707591856,32.24001334327514L215.90617261788813,35.09366289994968L200.29196615590206,39.40680577238173L187.71877802833063,44.769956017236325L177.63706311342756,50.858194239748315L169.4502226839945,57.44391840462522L162.66570643504798,64.37454664755393L156.91256568061866,71.54813715350824L151.91895428364148,78.89545913545598L147.48528498872713,86.36824868065094L143.46246292998507,93.93176255807185L139.73600152724268,101.56004446253723L136.2147391955617,109.2328489065828L132.82273453267914,116.93356567491149L129.49320696055256,124.64773751370521L126.16367938842599,132.36190935249894L122.77167472554342,140.06262612082762L119.25041239386249,147.7354305648732L115.52395099112013,155.3637124693386L111.50112893237812,162.92722634675954L107.06745963746386,170.4000158919545L102.0738482404868,177.74733787390227L96.32070748605761,184.9209283798566L89.53619123711132,191.85155662278538L81.34935080767849,198.43728078766236L71.26763589277579,204.5255190101745L58.69444776520481,209.88866925502924L43.080241303219196,214.20181212746152L24.34621684518919,217.05546168413633L3.493206960552243,218.0623348021624L3.493206960552243,218.0623348021624L0,218.03470723826067L0,190.61133602269132L0,163.18796480712197L0,135.76459359155263L0,108.34122237598328L0,80.91785116041393L0,53.494479944844585L0,26.071108729275238L0,-1.3522624862941086L252,-1.3522624862941086L504,-1.3522624862941086L504,26.071108729275238L504,53.494479944844585L504,80.91785116041393L504,108.34122237598328L504,135.76459359155263L504,163.18796480712197L504,190.61133602269132Z'
const end =
  'M0,198.47868323936274L4.927028427960408,206.02871397201466L11.93725138272032,213.71099149842013L22.20984708937999,221.034554053252L38.419917256266814,227.6527556580375L65.18825228558191,232.7633822265229L104.68485444720656,234.82977872657665L104.68485444720656,234.82977872657665L144.18145660882874,232.7633822265232L170.94979163814477,227.652755658038L187.15986180503202,221.03455405325258L197.4324575116921,213.71099149842075L204.4426804664522,206.02871397201534L209.55669285362313,198.14571060477368L213.49875943621376,190.14123492852747L216.6785335463443,182.0587480265382L219.34296743530004,173.9239532585937L221.64982920279115,165.75306376812097L223.7054669341448,157.55691088670665L225.58541432472487,149.34313699247687L227.3463210486864,141.11744544980337L229.03330750837762,132.8843621970575L230.68485444720648,124.64773751370622L232.33640138603536,116.41111283035495L234.02338784572657,108.17802957760907L235.7842945696881,99.9523380349356L237.6642419602681,91.7385641407058L239.71987969162174,83.54241125929147L242.02674145911286,75.37152176881874L244.69117534806858,67.23672700087423L247.87094945819908,59.154240098884955L251.81301604078962,51.149764422638725L256.9270284279605,43.26676105539707L263.9372513827204,35.58448352899161L274.2098470893801,28.26092097415973L290.4199172562667,21.642719369374305L317.18825228558194,16.532092800888876L356.6848544472066,14.465696300835148L396.18145660882567,16.532092800888222L422.9497916381429,21.642719369373268L439.15986180503097,28.26092097415861L449.4324575116914,35.58448352899036L456.4426804664517,43.26676105539579L461.55669285362274,51.1497644226374L465.4987594362135,59.15424009888365L468.67853354634417,67.23672700087295L471.3429674352999,75.37152176881747L473.64982920279107,83.54241125929025L475.70546693414474,91.73856414070463L477.58541432472487,99.95233803493443L479.3463210486864,108.17802957760796L481.03330750837756,116.41111283035387L482.6848544472064,124.64773751370517L484.3364013860353,132.88436219705648L486.0233878457266,141.11744544980237L487.78429456968803,149.3431369924759L489.6642419602681,157.55691088670574L491.7198796916217,165.75306376812011L494.0267414591128,173.92395325859286L496.69117534806855,182.05874802653742L499.87094945819905,190.14123492852673L503.8130160407896,198.145710604773L504,198.47868323936274L504,224.5632103765343L504,250.6477375137059L252,250.6477375137059L0,250.6477375137059L0,224.5632103765343Z'

export class PathAnimation extends React.Component {
  startRef = React.createRef()
  endRef = React.createRef()

  componentDidMount() {
    this.playAnimation()
  }

  playAnimation() {
    TweenMax.to(this.startRef.current, 1, {
      morphSVG: this.endRef.current,
      yoyo: true,
      repeat: -1,
      repeatDelay: 0.5,
      ease: Power2.easeInOut,
    })
  }

  render() {
    return (
      <svg width={500} height={400} className={'ba b--black'}>
        <g id="endPaths" style={{ visibility: 'hidden' }}>
          <path id="end" d={end} ref={this.endRef} />
        </g>
        <g id="startPaths" fill={'red'}>
          <path d={start} id="start" ref={this.startRef} />
        </g>
      </svg>
    )
  }
}

This is the error that is generated:

invalid morphSVG tween value: [object SVGPathElement]

I don't understand how I could solve it.

Thank you very much


Solution

  • It sounds like you just forgot to load MorphSVGPlugin. And don't forget that if you're using a build process that utilizes tree shaking, you'll need to reference MorphSVGPlugin somewhere in your code so that your bundler doesn't accidentally flag it as unused code and dump it. Kinda like:

    import MorphSVGPlugin from "yourLocation/MorphSVGPlugin.js";
    
    const plugins = [MorphSVGPlugin]; //just to prevent tree shaking from dumping it. 
    
    TweenMax.to(... {morphSVG:...});
    

    Also note that MorphSVGPlugin is a membership benefit of Club GreenSock, so it's not in the public downloads or NPM. You download it from your account at greensock.com. You can try it for free on codepen too - see https://greensock.com/try-plugins

    If you need any help, there are dedicated forums at https://greensock.com/forums