Jump to content

Search the Community

Showing results for tags 'state'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


  • GreenSock Forums
    • GSAP
    • Banner Animation
    • Jobs & Freelance
  • Flash / ActionScript Archive
    • GSAP (Flash)
    • Loading (Flash)
    • TransformManager (Flash)

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge


There are no results to display.

Find results in...

Find results that contain...

Date Created

  • Start


Last Updated

  • Start


Filter by number of...


  • Start



Personal Website



Company Website



Found 7 results

  1. Hi I built a dropdown navigation menu with gsap you can see a live example here https://sample.blinkpayment.co.uk/blink-learning-podcasts/blink-payment-insights-the-impact-of-contactless-payments-on-businesses Sometimes bugs can be created either randomly or by rapidly hovering over multiple dropdowns in quick succession. What are some ways I could make this code more reliable and better manage state for all of my animations. My codebase is vanilla with typescript. Live example https://sample.blinkpayment.co.uk/blink-learning-podcasts/blink-payment-insights-the-impact-of-contactless-payments-on-businesses Gist example of gsap menu code https://gist.github.com/samducker/3a1debb3a5816addddf76d3e6341927b Video of issues https://share.cleanshot.com/GJb8CW52
  2. Hi, I am trying to store a timeline to the useState hook in react, so that I use the state variable to control the timeline. I have been able to get this to work easily with React class Components, via storing a timeline to the state, but it is not working in useState for some reason. Does anyone know what I am doing wrong here? Thank you for any pointers! In my code example, onClick events on buttons are doing things that other events might do, just so it keeps it simple. Desired behavior: 1. Click first button, and it stores an array of classNames to a state hook. The JSX then uses this array to render elements (in this case it is divs). 2. Click the second button, and it calls a function that creates a timeline. It passes the array of classNames to this function, so that they will be used in the green sock timeline. 3. Click the third button and play the timeline. Actual behavior: Step three is not working. The timeline logs to the console, showing that it is stored to the state hook, but won't play. If I create the timeline in the actual onClick listener of the button (and pass the classNames stored on state to it), it does work. But this solution is not good because you are not storing the timeline anywhere to control, etc. This code should work, if you import it with any react app that has greensock installed (and uuid for keynames, but that can be removed for testing). Also, starter pen for green sock and codepen isn't working, so if anyone knows how to easily import the TimelineMax into codepen, copy and pasting this code should work right away. import React, { useState } from "react"; import { v4 as uuid } from "uuid"; import { CSSPlugin, TimelineMax } from "gsap/all"; const plugins = [CSSPlugin]; const createTimeline = (elements) => { // add a dot to the class names let elementClassSelectors = elements.map((className) => `.${className}`); const tl = new TimelineMax({ paused: true }); tl.to(elementClassSelectors, 2, { x: 100 }); return tl; }; export function AnimatedComponent() { let [timeline, setTimeline] = useState(null); let [elementsToAnimate, setElementsToAnimate] = useState([]); return ( <div className="component-frame"> <div className="display-animation"> {elementsToAnimate.map((elementClassName, i) => { // could use useRef here, but instead just adding classNames that can be used in green sock return ( <div className={`image ${elementClassName}`} key={uuid()}> I am image {i} </div> ); })} </div> <div className="controls" style={{ display: "flex", flexDirection: "column", alignItems: "flex-start", margin: "auto", }} > {/* These functions will actually be triggered by various events. But have them fired by buttons for now. */} <button onClick={(e) => { e.preventDefault(); let elementClassNames = [ "some-image", "some-other-image", "another-image", ]; setElementsToAnimate(elementClassNames); }} > CLICK FIRST: store new elements to state </button> <button onClick={(e) => { e.preventDefault(); let newTimeline = createTimeline(elementsToAnimate); setTimeline(newTimeline); }} > CLICK SECOND:create timeline and store it to state (seems to be working) </button> <button onClick={(e) => { e.preventDefault(); console.log("see if the timeline is on the state:", timeline); timeline.play(); }} > CLICK THIRD: play the timeline on the state (not working) </button> <button onClick={(e) => { e.preventDefault(); let temporaryTimeline = createTimeline(elementsToAnimate); temporaryTimeline.play(); }} > CLICK FOURTH: create timeline and don't store it to state (working, but not good/ need the timeline on the state) </button> </div> </div> ); }
  3. Hello everyone, since recently I started using React with GSAP. I have little experience in both, so the struggle is real. I am trying to create something very simple, a full screen menu that you can show/hide. When i am trying to debug this, i can see the state changing, and if I try to print within the `toggleMenu()`, method, i can see the state is changing however `timeline.play()`, simply doesn't do anything. I tried also removing the if case for play and reverse but still no effect. Its just atht my timeline doesnt want to play. I also tried using `componentDidUpdate()` but still no success. in that case my code looked like this: toggleMenu() { this.setState({ visible: !this.state.visible }); } componentDidUpdate(prevProps, prevState){ const {visible: preVisible} = prevState; const { visible } = this.state; if (visible && visible !== preVisible) { this.timeline.play(); } } componentDidMount(){ this.timeline = new TimelineLite({ paused: true }) .to(this.menuRef.current, 0.5, {autoAlpha: 1}); // .staggerTo(this.listNodes, 0.3, { opacity: 1,y: 0}, 0.2, "-=0.3"); } This is my container, where the magic is supposed to happen: import React, { Component } from "react"; import Hamburger from "./hamburger.jsx"; import Menu from "./menu.jsx"; import Logo from "./misc/Logo.jsx"; import { TweenMax, TimelineLite, CSSPlugin } from "gsap/all"; import { Transition } from "react-transition-group"; class MenuContainer extends Component { constructor(props) { super(props); this.state = { visible: false }; this.toggleMenu = this.toggleMenu.bind(this); this.timeline = null; this.menuRef = React.createRef(); } toggleMenu() { console.log(this.state.visible) this.state.visible ? this.timeline.reverse() : this.timeline.play(); this.setState({ visible: !this.state.visible }); } componentDidMount(){ this.timeline = new TimelineLite({ paused: true }) .to(this.menuRef.current, 0.5, {autoAlpha: 1}); // .staggerTo(this.listNodes, 0.3, { opacity: 1,y: 0}, 0.2, "-=0.3"); } render() { const { visible } = this.state; let logoColor = "#3e444e"; //blue if (visible) logoColor = "#ffffff"; //White return ( <div className="nav-wrapper"> <div className="top-bar"> <div className="top-bar-left"> <Logo logocolor={logoColor} /> </div> <div className="top-bar-right"> <div> <Hamburger handleMouseDown={this.toggleMenu} menuVisibility={visible} /> </div> </div> </div> <div> <Menu visible={visible} menuRef={this.menuRef} /> </div> </div> ); } } export default MenuContainer; This is the menu element where I am setting the `ref`: import React, { Component } from "react"; import { apiUrl } from './../../methods'; class Menu extends Component { constructor(props) { super(props); this.state = { links: [], isLoading: false, error: null }; } componentDidMount() { const targetUrl = apiUrl("/sapi/main_menu_items.json"); this.setState({ isLoading: true }); fetch(targetUrl) .then(response => { if (response.ok) { return response.json(); } else { throw new Error("Something went wrong...."); } }) .then(data => this.setState({ links: data.links, isLoading: false })) .catch(error => this.setState({ error, isLoading: false })); //Passing the data to state.links and changing isLoading to false } render() { const { links, isLoading, error } = this.state; const listItems = links.map((link, index) => ( <li className="menu-link v-link" key={link.slug} // ref={li => (this.listNodes[index] = li)} > <a href={link.slug}>{link.title}</a> </li> )); if (error) return <p>{error.message}</p>; if (isLoading) return <p>Loading....</p>; return ( <div className="full-screen-menu" ref={this.props.menuRef}> <div className="grid-y grid-frame align-middle"> <div className="cell auto links-wrapper"> <div className="grid-container full-height"> <div className="grid-x align-middle full-height"> <div className="cell small-12"> <ul className="links">{listItems}</ul> </div> </div> </div> </div> <div className="cell shrink"> <div className="grid-container"> <div className="grid-x"> <div className="cell small-12 text-right text-white"> <ul> <li> <a className="text-white">+31 638 501 270</a> </li> <li> <a className="text-white">hello@whale-agency.com</a> </li> </ul> </div> </div> </div> </div> </div> </div> ); } } export default Menu; And here is the hamburger, that is being clicked: import React, { Component } from "react"; import MenuOpener from "./misc/menuOpener.jsx"; import MenuCloser from "./misc/menuCloser.jsx"; class Hamburger extends Component { render() { if (!this.props.menuVisibility) { return ( <MenuOpener className="menu-button" onMouseDown={this.props.handleMouseDown} /> ); } else { return ( <MenuCloser className="menu-button" onMouseDown={this.props.handleMouseDown} /> ); } } } export default Hamburger; Last but not least, the important css: .full-screen-menu { position: absolute; opacity: 0; visibility: hidden; width: 100vw; height: 100vh; bottom: 0; left: 0; background: url(/images/menu-background.jpg); background-size: cover; background-position: center; background-repeat: no-repeat; z-index: 999; } Hopefully someone can help me go in the right direction. Greetings, Nikolay
  4. Hi GSAP enthusiasts, I am searching for the best way to propagate state changes on timeline level (e.g. "timeline was paused", "timeline started playing again"). There are event callbacks: "onComplete", "onUpdate", "onStart", "onReverseComplete" or "onRepeat". But none of them is working for me... I am looking for something like "onStateChange" that I can listen for, to properly propagate state changes. e.g. tl..eventCallback('onStateChange', function(evt) { if (tl.paused()) { /*...*/ } else { /*...*/ } }) Is there any recommended way to achieve this? Any hint appreciated. Happy animating!
  5. The animation module for Angular 1 was a game changer, and has since been copied by other libraries like Vue and React. For Angular 2, they decided to take a different approach, and create their animation engine. At one point in time, they were looking at using GSAP, but went with using a declarative syntax with the Web Animations API instead. The end result has been pretty craptastic. Nobody uses it, not even the Angular Material team. So how do you animate state changes like this without using their engine? transition('inactive => active', animate('100ms ease-in')), transition('active => inactive', animate('100ms ease-out')) I didn't know if that was possible using GSAP, but @apploud shared a script with me the other day that can do something similar, allowing you to create animations like this. "fadeIn => fadeOut": () => TweenLite.to(this.element.nativeElement, 0.5, { autoAlpha: 0 }), "fadeOut => fadeIn": () => TweenLite.to(this.element.nativeElement, 0.5, { autoAlpha: 1 }) It's just a very basic implementation right now, and needs some work, but it could be really helpful for Angular users who want to use GSAP. I don't have time to work on it, but it would be awesome if somebody else could work on it, and maybe make it into an NPM module. Like I said, it's pretty basic right now, so it's not going to work with wildcard or void states like this. // enter transition "void => *" : () => TweenLite.from(this.element.nativeElement, 1, { autoAlpha: 0 }) // leave transition "* => void" : () => TweenLite.to(this.element.nativeElement, 0, { autoAlpha: 0 }) You can see how it works in this demo. https://www.webpackbin.com/bins/-KlC3WIhC60G0V7Ck5CN
  6. Hey guys Sorry for no codepen demo as I'm working on a large website and couldn't just extract the bits for the sake of a demo. Hopefully the screenshots + gifs will suffice. Scenario: I have a pinned section that sequentially shows + hides 2 elements as you scroll. When you scroll to the element initially, they should be hidden and then fade in and out again until the element is unpinned. Problem: Both elements are initially visible and overlapping each other when the page first loads. If i scroll down the page and run through the animation, and then scroll back up again, the animation ONLY THEN works correctly. So it's as if the final state of the animation is setting it correctly, but I can't seem to set it up to do that from the get go. Some Gifs: The problem: http://i.imgur.com/QVPga7u.mp4 How it should be: http://i.imgur.com/0zKVUo8.mp4 (note this happens once I've scrolled down and then back to the top again) The Javascript TweenMax.set(".infographic-text-wrapper", { opacity: 0, scale: .9 }); // this has no effect var controller = new ScrollMagic.Controller(); // tween var tween = new TimelineMax() .fromTo('.infographic-text-wrapper-1', 1, { opacity: 0, scale: .9 }, { opacity: 1, scale: 1 }) .fromTo('.infographic-text-wrapper-1', 1, { opacity: 1, scale: 1 }, { opacity: 0, scale: .9 }) .fromTo('.infographic-text-wrapper-2', 1, { opacity: 0, scale: .9 }, { opacity: 1, scale: 1 }) .fromTo('.infographic-text-wrapper-2', 1, { opacity: 1, scale: 1 }, { opacity: 0, scale: .9 }) // scene var scene = new ScrollMagic.Scene({ triggerElement: "#what-we-offer", triggerHook: 'onLeave', triggerOffset: 800, duration: 3000, offset: -150 }) .setPin("#what-we-offer") .setTween(tween) .addTo(controller); The CSS And then the CSS used to set the initial state (although this doesn't seem to have any effect) .infographic-text-wrapper { position: absolute; top: 0; left: 0; opacity: 0; transform:scale(.9); } Final note is that I have tried the suggestions on this page, but to no avail. So frustrated and the lack of google search results on the page mean I'm probably being really stupid, but at this point I would welcome any help I can get...
  7. Hey guys! I am fairly new to GSAP and i am learning it by building stuff. I have an svg in the middle of the page and i would like it to animate to the left and then display the content of the page (which i did not coded yet). When the user clicks it again, i would like to return to its initial state and hide the content of the page. Throughout the past few hours, I tried various on click functions with if else statements but nothing seems to work. With the show/hide part of the content i will deal with it later, for the moment i would like to learn how to fix the clicking part. Thanks in advance!