Jump to content
Search Community

TimelineMax .set and .stagger* not a function in React component (webpack issue?)

flowen test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hi, 

 

I have a parent component and a couple of child components. 

 

In the parent component I use the intersection observer to fire animations I created in the child components.

 

The child components simply return a TimelineMax object and I play this in the parent.

 

All good.

 

Until I get these strange Webpack errors saying:

Quote

Volumes/Data/DOCUMENTS/_htdocs/mevishaslam.com/gatsby-styled-components/src/components/Title.js:93 Uncaught TypeError: gsap__WEBPACK_IMPORTED_MODULE_4__.TimelineMax.set is not a function

 

and

 

Quote

Uncaught TypeError: gsap__WEBPACK_IMPORTED_MODULE_4__.TimelineMax.staggerTo is not a function

 

 

I can fix it by replacing TimelineMax with TweenMax so I feel confident saying that somehow TimelineMax doesnt' have these methods. Though the doc's say they do.

 

Sorry I can't post a codepen now (I can do later if this help). Here's the code affected:

 

import { TimelineMax, TweenMax } from 'gsap'

export default class TitleInnerRef extends Component {
  constructor(props) {
    super(props)

    this.el = React.createRef()
    this.st = null

    this.tl = new TimelineMax()
  }

  componentDidMount() {
    this.st = new SplitText(this.el, { type: 'lines', linesClass: 'overflow' })
    TimelineMax.set(this.st.lines, { yPercent: 150 })
  }

  title = () => this.props.title

  show = () => {
    TimelineMax.staggerTo(this.st.lines, .5, { yPercent: 0 }, .05)

    return this.tl
  }

  render() {
    return (
        <RefTitle
          regular = {this.props.regular}
          _ref={node => (this.el = node)}
          dangerouslySetInnerHTML={{ __html: this.title() }}>
        </RefTitle>
    )
  }
}

 

 

 

 

 

Link to comment
Share on other sites

23 minutes ago, flowen said:

I can fix it by replacing TimelineMax with TweenMax so I feel confident saying that somehow TimelineMax doesnt' have these methods. Though the doc's say they do.

 

It looks like you're getting confused by "static" and "instance" methods. In the docs, a static method will include the class name, like TweenMax.set(). An instance method will look like .set(). Every method for a timeline is an instance method except for one, TimelineMax.exportRoot().

 

An instance method means it's only available on an instance, so you have to create one.

 

const tl = new TimelineMax()
tl.staggerTo(this.st.lines, .5, { yPercent: 0 }, .05)

 

That's really just a convenience method for this.

 

const tl = new TimelineMax()
tl.add(TweenMax.staggerTo(this.st.lines, .5, { yPercent: 0 }, .05))

 

 

Timelines are good for sequencing. Check out this page and video.

https://greensock.com/sequence-video

 

 

 

  • Like 3
Link to comment
Share on other sites

3 hours ago, OSUblake said:

 

It looks like you're getting confused by "static" and "instance" methods. In the docs, a static method will include the class name, like TweenMax.set(). An instance method will look like .set(). Every method for a timeline is an instance method except for one, TimelineMax.exportRoot().

 

An instance method means it's only available on an instance, so you have to create one.

 


const tl = new TimelineMax()
tl.staggerTo(this.st.lines, .5, { yPercent: 0 }, .05)

 

That's really just a convenience method for this.

 


const tl = new TimelineMax()
tl.add(TweenMax.staggerTo(this.st.lines, .5, { yPercent: 0 }, .05))

 

 

Timelines are good for sequencing. Check out this page and video.

https://greensock.com/sequence-video

 

 

 

 

Thanks @OSUblake for pointing out the difference in static and instance methods. I'll have a look later on the difference.

 

I do understand though what you're pointing out. 

 

But I don't understand why webpack is telling me the function doesn't exist. I do import TweenMax in the file.

 

Also sorry for posting an (unfinished) example without showing any sequences, they will be there :)

Link to comment
Share on other sites

It's a JavaScript error. Look at the console here.

 

See the Pen aRjaqy by osublake (@osublake) on CodePen

 

 

You need to fix the errors. Use TweenMax...

 

componentDidMount() {
  this.st = new SplitText(this.el, { type: 'lines', linesClass: 'overflow' })
  TweenMax.set(this.st.lines, { yPercent: 150 })
}

show = () => {
  TweenMax.staggerTo(this.st.lines, .5, { yPercent: 0 }, .05)
}

 

 

Or use timeline instances...

 

componentDidMount() {
  this.st = new SplitText(this.el, { type: 'lines', linesClass: 'overflow' })
  const tl = new TimelineMax()  
  tl.set(this.st.lines, { yPercent: 150 })
}

show = () => {
  const tl = new TimelineMax()  
  tl.staggerTo(this.st.lines, .5, { yPercent: 0 }, .05)
}

 

  • Like 3
Link to comment
Share on other sites

I completely understand now @Osublake

 

Thanks again for the explanation.

 

 

Anyone reading this.. from different child components I return the timeline to the parent to play it.

When using a timeline instance I noticed, the .set wouldn't immediately work.

 

Which makes sense because I pause the master timeline in the parent component.

 

So went for Tweenmax in this case :)

Link to comment
Share on other sites

I can see where you're trying to go with this, so maybe something like this. Just play the timeline on show.

 

export default class TitleInnerRef extends Component {
  constructor(props) {
    super(props)

    this.el = React.createRef()
    this.st = null

    this.tl = new TimelineMax({ paused: true })
  }

  componentDidMount() {
    this.st = new SplitText(this.el, { type: 'lines', linesClass: 'overflow' })
    TimelineMax.set(this.st.lines, { yPercent: 150 })
    this.tl.staggerTo(this.st.lines, .5, { yPercent: 0 }, .05)
  }

  title = () => this.props.title

  show = () => {
    return this.tl.play();
  }

  render() {
    return (
        <RefTitle
          regular = {this.props.regular}
          _ref={node => (this.el = node)}
          dangerouslySetInnerHTML={{ __html: this.title() }}>
        </RefTitle>
    )
  }
}

 

  • Like 5
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...