Jump to content

Rodrigo last won the day on March 17

Rodrigo had the most liked content!


  • Content Count

  • Joined

  • Last visited

  • Days Won


Rodrigo last won the day on March 17

Rodrigo had the most liked content!

Community Reputation

2,640 Superhero

About Rodrigo

  • Rank
    Advanced Member

Contact Methods

  • Skype

Profile Information

  • Gender
  • Location
    Santiago - Chile

Recent Profile Visitors

22,444 profile views
  1. Ha!!! is already complicated enough, so no thanks!!!
  2. I could tell you, but after I'd have to kill you... Absolutely is a matter of having the time to create the samples and update the guide as well. Is definitely in my to-do list:
  3. Hi and welcome to the GreenSock forums. Sorry to hear that you're experiencing problems with GSAP. Unfortunately it seems to be an issue with some CORS issue accessing bundlephobia.com's API, so the live sample is not working, for me at least. In this post is discussed how to create and toggle animations using the Hooks API: Also you can check a live simple example here as well: https://stackblitz.com/edit/gsap-react-hooks-toggle For I can see in your code you're using two different timelines to affect the same elements into different values. Ideally try to create a GSAP instance that you can toggle for each sub-menu element. Also you're adding new instances to the timeline every time the component is updated, so try to add an empty array when creating the GSAP instances so that code runs only when the component is mounted and toggle the animations using another useEffect call only when the open state property is updated. Hopefully this can help you as you try to get a working live sample so we can take a better look at it. Happy tweening!!
  4. Hi, you can create the split text as a property in the component's class, in the constructor: constructor (props) { super(props); this.title = null; this.titleChars = null; } Here this.title should point to a ref in the render method Then in the component did mount method you can create the SplitText instance and assign the chars to the property created in the constructor: componentDidMount () { const mySplit = new SplitText(this.title, { type: "words, chars", position: "absolute" }); this.titleChars = mySplit.chars; // array of DOM elements (<div> tags) TweenMax.staggerTo(this.titleChars, 1, {x: 10, y:-10, rotation: 180, autoAlpha: 0}, 0.1); } That is working for me, give it a try and let us know how it works. Happy tweening!!
  5. You could filter the visible elements and render just those using RTG, like in this sample: https://stackblitz.com/edit/gsap-react-simple-transition-group?file=simple-transition.js Of course that is just one element but is the same principle. When the show value in the state is toggled the element is animated in/out with the consequent mount/unmount. Instead of managing the show value on each component's you could pass it as a prop to each element. If you ask me I would use array.filter() to get a filtered version of the array elements that should be visible and render just those: https://stackblitz.com/edit/gsap-react-transition-group-list In that sample as soon as you remove an element, the array is reduced but the element is still rendered. As the animation-out is completed the element is removed from the App's tree. Take a look at both samples and hopefully you'll get a good grasp on how to tackle your situation. Finally you could take a look at this article by Addy Osmani: https://addyosmani.com/blog/react-window/ Happy Tweening!!
  6. You could use a mix of the code in these codepens: https://codepen.io/GreenSock/pen/zcmpo https://codepen.io/GreenSock/pen/uhKIy Happy Tweening!!!
  7. You're welcome. For styles I'm an old fashioned guy and use SASS in separate files. I just don't like styled components. There used to be this concept called "Separations of Concerns" which I still follow to this day. IMHO styles go with styles, pure JS goes with pure JS and React code goes with React code, but again that's just my and my two cents on the subject. If you use breakpoints for animations my advice would be to use the context API and the root component of your app to keep track of the screen size. Like that you can check the screen size when creating/running your animations on every component in the app without the need of passing props down the component tree. Of course if at some point you plan to implement redux you can use it as well to spread the screen size from a single component that listens to the window resize event. The jumpy behaviour could be related to sub-pixel rendering but if you're using x and y that shouldn't be an issue. Perhaps the content your animating is creating the issue, maybe large images with transparency or shadows. Those things normally cause a lot of stress on the rendering engine. This is just on safari? Chrome, Firefox, Edge work OK? Happy Tweening!!
  8. Ahh yes my bad. I meant a Draggable trigger: https://greensock.com/docs/Utilities/Draggable Scroll down a bit in the features and you'll find it. Also here is a simple example: https://codepen.io/rhernando/pen/IiHgq Happy Tweening!!
  9. Hi and welcome to the GreenSock forums. Honestly I don't think using transition group is a good fit for the type of site you have in mind. Transition group fits better in cases you need to animate elements that will be mounted/unmounted in the React app, rather than regular animations. The best approach I can think of is to use either React's context API, redux/mobx or direct props to pass a method to all child components to add the particular timeline of each component to the master one. I would avoid doing this at all cost: // create react class class Box1 extends Component {} export default Box1; export const Timeline1 = () => {}; Mainly because there is no guarantee that the DOM element will be mounted when the file actually reaches the point of the function definition that creates and returns the timeline. Instead create the timeline inside the component (the react-way soto speak) and then use the method created in the parent component to send that animation and add it to the master timeline. Something like this: Parent Element class App extends Component { constructor (props) { super(props); this.masterTl = new TimelineMax({useFrames:true, paused:true}); this.addChildTimeline = this.addChildTimeline.bind(this); } // method to add child timelines to the master addChildTimeline (childTl, position) { this.masterTl.add(childTl, position); } render() { return <div> <Box1 addChild={this.addChildTimeline} /> </div>; } Child Component class Box1 extends Component { constructor (props) { super(props); this.box1 = null; this.tl = new TimelineLite({useFrames:true, paused:false}); } componentDidMount() { this.tl .to(this.box1, 200, { opacity: 1, }) // here you'll have to find a way to plug this duration value .to('.box-1', duration*2, { scale: 2.5, top: "80%", left: '-30%', }, "-=200"); this.props.addChild(this.tl, "+=200"); } render () { return <div> <div ref={div => this.box1 = div}> // box1 content here </div> </div>; } As you can see transition group is not needed at all and for this setup it will only make things more complicated. Unfortunately I don't have time right now and for the foreseeable future to create a concrete sample of this, so I hope that this simple advice is enough to get you started. Happy Tweening!!
  10. Hi and welcome to the GreenSock forums. Yeah this is a bit more complicated since you're using SVG and regular DOM nodes. In this sample I'm using just DOM nodes so everything works in the intended way: https://codepen.io/rhernando/pen/Ehjbd Perhaps you could use a trigger or remove the <div> tag from the SVG altogether and use some other way to position it. I'm not an SVG expert and is the first time I see the <foreignObject> tag actually and my best guess is that using that approach could be the cause of your issues, so beyond what's in my sample and that particular advice I don't know if I can do much more. Happy Tweening!!!
  11. If you ask me I would go with a sprite sheet and PIXI, but if that is not an option you could try to plug GSAP into some of these libraries: https://github.com/buzzfeed/libgif-js https://github.com/geelen/x-gif Happy Tweening!!!
  12. Hi and welcome to the GreenSock forums. Unfortunately I don't have a lot of time to check the details of your demo and see what could be causing the issue. As far as passing a Component Ref down as prop, those are objects and there is definitely nothing against passing objects as props, since you're not actually passing the object but the reference, but is not something I would do. Instead of passing the result of the Ref callback (as that suspicious article you mention says ) I would try to use Forwarding Refs in order to get the DOM elements of each element you want to make draggable in the parent and create the draggable instances there, where you have direct access to the reference of the actual DOM node that would act as the bounds. Since you're using functional components it should be fairly easy. In this sample instead of creating a TweenLite instance you would create a Draggable one: https://stackblitz.com/edit/react-forwarding-refs-gsap Another alternative is to take advantage of the fact that bounds can be passed as an object, so you can use the dimensions of the parent component and pass it down as a prop to the child component and use that rectangle to enforce such bounds using positioned elements, offsetTop and offsetLeft to calculate the bounds when the Draggable instance is created. As you can see there are a couple of alternatives that I can think right of the top of my head. i'm pretty sure that other solutions are possible and that hopefully these will help you getting started. Happy Tweening!!
  13. Well I was creating a sample an Jack beat me to it. Also a piece on friendly advice. Try to avoid updating the state of any component on events that are triggered a lot like mouse move or scroll. It could create quite a burden in the app since that component re-renders and so it will any child component in it even if they don't re-render because of the state update, Reat still will look and do a shallow comparison to see if something has to be updated. If possible try to set up an event emitter and store the mouse position outside the class, remember that you're working with ES6 modules, which means that you can export the event emitter from the main file (or other file if you want), create the event listener in the new cursor file and emit the event in the parent component, that will be far cheaper in terms of processing than updating the state on every mouse move. If you take a look at this scroll spy library, you'll see that the guy does and stores all the calculations in an object and then compares those values with the ones stored. Once the scroll value exceeds the value of one of those items the state is updated only once: https://github.com/makotot/react-scrollspy/blob/master/src/js/lib/scrollspy.js#L191-L201 Happy Tweening!!!
  14. Just the beginning https://greensock.com/docs/TimelineLite
  15. Hi, I haven't used hooks a lot, since I've been extremely busy with literally no free time so I couldn't tell you in this one. The one solution (that you probably are aware of) I can suggest is to use a regular class component just for the switch element. I know is not the ideal case, but with a component that small the overhead created by the extra code shouldn't be noticeable, unless we're talking about hundreds of instances. You can compare the outcome of this small snippet in Babel's repl playground: const MyComponent = () => { const tl = "TimelineInstance"; return <div></div>; } class ClassComponent extends Component { constructor(props){ super(props); } render() { return <div></div>; } } Of course Babel is going to add a few lines at the start of the outcome for the class declaration but you'll find this: var MyComponent = function MyComponent() { var tl = "TimelineInstance"; return React.createElement("div", null); }; var ClassComponent = /*#__PURE__*/ function (_Component) { _inherits(ClassComponent, _Component); function ClassComponent(props) { _classCallCheck(this, ClassComponent); return _possibleConstructorReturn(this, _getPrototypeOf(ClassComponent).call(this, props)); } _createClass(ClassComponent, [{ key: "render", value: function render() { return React.createElement("div", null); } }]); return ClassComponent; }(Component); As you can see the difference is not much, for something as simple as this of course, but as I mentioned, the gain in a small component that it doesn't have hundreds of instances the overhead is minimal and most likely unnoticeable. Actually there is not a lot of issue in creating instances outside the declaration of a React component. Keep in mind that those are just object constructors, nothing more. Also is very important to keep in mind that the bundling tools (today almost everyone uses Webpack) creates independent, encapsulated modules so each file has no communication with the global scope unless is set up in such way, which @PointC's suggestion doesn't so it should be very safe to do so. Hopefully this comes as helpful. Happy Tweening!!