Jump to content
Search Community

Invalid property morphSVG in React

MRParag test
Moderator Tag

Go to solution Solved by ZachSaucier,

Recommended Posts

I am getting Invalid property morphSVG set to <svg>.......</svg> Even Though i have registerd the plugin using Gsap.registerPlugin(DrawSVGPlugin)

 

Here is my Full Code.

 

import React, { Component, createRef } from 'react';

import Gsap from 'gsap';
import DrawSVGPlugin from 'gsap/DrawSVGPlugin';

import NavigationStyler from './Navigation.module.scss';

const MenuTimeline = Gsap.timeline();

class Navigation extends Component {
    constructor(props) {
        super(props);
        this.MenuBackDiv = createRef();
        this.Menu = createRef();
        this.MenuOpenIconSVG = createRef();
        this.MenuCloseIconSVG = createRef();
        this.state = {
            menuOpen: false
        }
    }

    componentDidMount() {
        Gsap.registerPlugin(DrawSVGPlugin);
    }

    switchNavigationWindow = (event) => {
        if (this.state.menuOpen) {
            MenuTimeline.to([this.Menu.current, this.MenuBackDiv.current], 1, {
                height: '0',
                ease: 'power3.inOut',
                stagger: 0.1,
            });

            this.setState({menuOpen: !this.state.menuOpen});
        }
        else {
            MenuTimeline.to(this.MenuOpenIconSVG.current, 0.5, {
                morphSVG: this.MenuCloseIconSVG.current
            }).to([this.MenuBackDiv.current, this.Menu.current], 1, {
                height: '100%',
                ease: 'power3.inOut',
                stagger: 0.1
            });

            this.setState({menuOpen: !this.state.menuOpen});
        }
    }

    render() {
        return (
            <>
                <div onClick={this.switchNavigationWindow} className={NavigationStyler.MenuIcon + " inline-flex flex-col gap-1"}>
                    <svg viewBox="0 0 32 32">
                        <path ref={this.MenuOpenIconSVG} className={NavigationStyler.MenuOpenIconSVG} d="M4 7v2h24V7zm0 8v2h24v-2zm0 8v2h24v-2z"/>
                        <path ref={this.MenuCloseIconSVG} className={NavigationStyler.MenuCloseIconSVG} d="M7.21875 5.78125l-1.4375 1.4375L14.5625 16l-8.78125 8.78125 1.4375 1.4375L16 17.4375l8.78125 8.78125 1.4375-1.4375L17.4375 16l8.78125-8.78125-1.4375-1.4375L16 14.5625z"/>
                    </svg>
                </div>
                <div ref={this.MenuBackDiv} className={NavigationStyler.MenuBackDiv}>
                </div>
                <div ref={this.Menu} className={NavigationStyler.Menu}>
                </div>
            </>
        );
    }
}

export default Navigation;

SCSS Code:

.MenuIcon {
    z-index: 1003;
    height: 40px;
    width: 40px;
    @apply absolute top-4 right-4;

    svg {
        width: 40px;
        height: 40px;
        fill: #FFFFFF;

        .MenuOpenIconSVG {
        }
        .MenuCloseIconSVG {
            visibility: hidden;
        }
    }

    &:hover {
        cursor: pointer;
    }
}

.MenuBackDiv {
    z-index: 1001;
    background-color: #202021;
    @apply absolute top-0 left-0 w-screen max-w-full;
}

.Menu {
    z-index: 1002;
    @apply bg-gray-200 absolute top-0 left-0 w-screen max-w-full;
}
Link to comment
Share on other sites

So sad that I didn't saw that... BTW Can you please tell me now why this morphing doesn't do anything when i target the morphed version of svg backword...?

switchNavigationWindow is now looking like this..:

switchNavigationWindow = (event) => {
    if (this.state.menuOpen) {
        MenuTimeline.to(this.MenuCloseIconSVG.current, 0.5, {
            morphSVG: this.MenuOpenIconSVG.current
        }).to([this.Menu.current, this.MenuBackDiv.current], 1, {
            height: '0',
            ease: 'power3.inOut',
            skewY: 2,
            stagger: 0.05,
        }, '-= 0.5');

        this.setState({menuOpen: !this.state.menuOpen});
    }
    else {
        MenuTimeline.to(this.MenuOpenIconSVG.current, 0.5, {
            morphSVG: this.MenuCloseIconSVG.current
        }).to([this.MenuBackDiv.current, this.Menu.current], 1, {
            height: '100%',
            ease: 'power3.inOut',
            skewY: -2,
            stagger: 0.05,
        }, '-= 0.5');

        this.setState({menuOpen: !this.state.menuOpen});
    }
}
Link to comment
Share on other sites

I'm guessing that the if runs first? So the close menu icon's path is morphed into the open icon's path. 

 

Then the next time the else runs, attempting to make the open menu's path morph into the close menu but at that point the paths are the same (because of your first morph tween). What you probably want to do instead is keep a variable reference of each state that's completely static. Then you have one actual path that you're morphing between your states. 

 

Additionally it'd probably be best to set up the animation beforehand and then use control methods to control the animation as described in my article about animating efficiently

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...