Search the Community
Showing results for tags 'gsap'.
-
When transforming 3D using perspective for svgs chrome there is always a bug that I face. For example on this web https://threeedy.surge.sh/ when all the elements are translated in 3D, there is a bug in the where it sticks on awkward positions. And this happens only in chrome , on firefox it stays in 3D transformation. Also in my portfolio web: https://obaidnadeem.surge.sh/ in the User Interface section I have done the same thing but getting the same bug in chrome while the firefox runs everything smoothly. Is their solution to this or am I doing something wrong? or the only solution is to wait until chrome team fixes bug from their end and extend support for Scalar Vector Graphics ?
- 4 replies
-
- svganimations
- gsap
-
(and 1 more)
Tagged with:
-
As i was using the angular 12 to build the webapp i'm trying to use the scroll trigger animation in my project, the thing is the initial animation is working fine. But when it comes to ScrollTrigger in doesn't works in angular. I dont know why... I want to target a particular class in HTML to animate it using the scrolltrigger plugin
- 7 replies
-
- gsap
- scrolltriger
-
(and 1 more)
Tagged with:
-
I am using gsap scrolltrigger to toggle a class that makes the container sticky. After the end of the animation when the class is removed it behaves weirdly. Here is the video link : https://drive.google.com/file/d/12WOmmK43dFBxvVLKuDPoAGnOAT4-b76L/view?usp=sharing As you can see in the video after the end of animation it moves it..... Is there any fix to this ? Javascript code : const canvas = document.getElementById('hero-lightpass'); const context = canvas.getContext('2d'); const frameCount = 45; const currentFrame = index => `./assets/medium_${(index + 1).toString().padStart(4, '0')}.jpg`; canvas.width = 600; const images = []; const airpods = { frame: 0, }; for (let i = 0; i < frameCount; i++) { const img = new Image(); img.src = currentFrame(i); images.push(img); } console.log(canvas.width); gsap.to(airpods, { frame: frameCount - 1, snap: 'frame', scrollTrigger: { trigger: '.sticky-wrapper', scrub: 0.5, markers: true, start: 'top 48px', end: 'center 49px', toggleClass: 'sticky', }, onUpdate: render, }); images[0].onload = render; const getheight = () => {}; function render() { console.log(images[0].naturalHeight); const h = images[0].naturalHeight; const w = images[0].naturalWidth; const aspect = h / w; console.log(aspect); canvas.height = aspect * canvas.width; context.drawImage(images[airpods.frame], 0, 0, canvas.width, canvas.height); }
-
Hello every one , i found so trouble in use scroll trigger with react three fiber , so can any one help me ? or i have to learn some thing befor ?? i saw an example but never see what i need to do thank's
- 7 replies
-
- scrolltrigger
- animation
-
(and 3 more)
Tagged with:
-
Hi there, I'm trying to build a seamless animation where my van image is centered in the middle with its light, and it is following the line. The white dot at the left is from another codepen: https://codepen.io/lisaschumann/pen/KKqMMoe which I used as a starting point. That point follows the path perfectly, but whenever I try to make my van follow the path in the middle it still takes the path position (-33%) Also, when I try to add my own path, it destroys the animation even more. I would like to use this as my own path <path id="line" d="M0,251.32C59.82,242,144.24,236.61,205,247c24,4.11,51.08,16.94,93.28,17.46,51.08.62,85.58-13.89,110.91-21.77,46.78-14.55,71.87-9.48,225,4.42,154.49,14,231.73,21,263.29,20.4,157.16-3.08,161.25-38.87,254.58-20.52,107,21,131.36,73.93,210.74,60.61,63.78-10.7,66.12-50.36,142.89-69.32,65.67-16.23,129.58.42,193.86,8.47,92.31,11.57,189.23,6,280.72-8.29,292.41-45.49,315.9,15,621.94-1.28,293.86-15.63,282.72-46.8,401-24.71,151.74,28.35,230.58,91,380.35,64,56.7-10.22,79.74-21.4,168-37.43,69.39-12.61,149.91-9.39,220.58-9.3,52.95.07,131.22-1.76,227.87-4.31" style="fill:none;stroke:blue;stroke-linecap:round;stroke-width:10px" /> Any help is massivly appriciated!
-
When I add pin to element background of scroll is visible Here's my code: gsap.registerPlugin(ScrollTrigger); function gsapanim(){ const locoScroll = new LocomotiveScroll({ el: document.querySelector(".scrollContainer"), smooth: true }); // each time Locomotive Scroll updates, tell ScrollTrigger to update too (sync positioning) locoScroll.on("scroll", ScrollTrigger.update); // tell ScrollTrigger to use these proxy methods for the ".smooth-scroll" element since Locomotive Scroll is hijacking things ScrollTrigger.scrollerProxy(".scrollContainer", { scrollTop(value) { return arguments.length ? locoScroll.scrollTo(value, 0, 0) : locoScroll.scroll.instance.scroll.y; }, // we don't have to define a scrollLeft because we're only scrolling vertically. getBoundingClientRect() { return {top: 0, left: 0, width: window.innerWidth, height: window.innerHeight}; }, // LocomotiveScroll handles things completely differently on mobile devices - it doesn't even transform the container at all! So to get the correct behavior and avoid jitters, we should pin things with position: fixed on mobile. We sense it by checking to see if there's a transform applied to the container (the LocomotiveScroll-controlled element). pinType: document.querySelector(".scrollContainer").style.transform ? "transform" : "fixed" }); // TIMELINE 1 const tl1 = gsap.timeline({scrollTrigger: { scroller: ".scrollContainer", trigger: '.header', start: "top top", end: "bottom 60%", scrub: 3, markers: false, id: 'header', pin: '.header', } }); tl1.to('.top__logo', { scale: 4, opacity: 1, ease: "none" }) const tlcs = gsap.timeline({scrollTrigger: { scroller: ".scrollContainer", trigger: '.header', start: "top top", end: "bottom 60%", scrub: 3, markers: false, pin: '.header', } }); tlcs.to('.top__smoke-child', { x: "-200%", opacity: 0, ease: "none", id: "header2" }) tl1.to('.top__logo', {scale: 5, opacity: 0, duration: 0.5}); tl1.to('.header', {opacity: 0, duration: 0.1}); tl1.to('.header', {display:"none", color: "black"}); // TIMELINE 2 const tl2 = gsap.timeline({scrollTrigger: { scroller: ".scrollContainer", trigger: ".section--main__ui_1", start: "-385px 28%", end: "999px 33%", markers: true, toggleActions: "restart none restart none", id: "tl2" } }); tl2.fromTo('.main__top_1', {opacity: 0}, {opacity: 1, duration: 1, delay: 1}) tl2.fromTo('.main__description_1', {opacity: 0}, {opacity: 1, duration: 1}) const tl3 = gsap.timeline({scrollTrigger: { scroller: ".scrollContainer", trigger: ".section--main__ui_2", start: "-385px 28%", end: "999px 33%", markers: true, toggleActions: "play restart restart none", id: "tl3", } }); tl3.fromTo('.main__top_2', {opacity: 0}, {opacity: 1, duration: 1, delay: 1}) tl3.fromTo('.main__description_2', {opacity: 0}, {opacity: 1, duration: 1}) // each time the window updates, we should refresh ScrollTrigger and then update LocomotiveScroll. ScrollTrigger.addEventListener("refresh", () => locoScroll.update()); // after everything is set up, refresh() ScrollTrigger and update LocomotiveScroll because padding may have been added for pinning, etc. ScrollTrigger.refresh(); P.S: My container is also called "scrollContainer"
- 7 replies
-
- gsap
- locomotive
-
(and 2 more)
Tagged with:
-
Hi everyone, just started with GSAP two days ago! I'm having a problem with my horizontal scroll layout where sections are overlapping each other to an extent that you can't even view the content in them. Also, a lot of margins are being added. If I put real data in these sections, the last section disappears from the viewport (due to margin/padding being added) What I want to achieve is horizontal scroll but sections should respect the width and margins instead of overlapping. Please suggest me what should I do...
- 9 replies
-
- horizontal scrolltrigger
- scrolltrigger
-
(and 1 more)
Tagged with:
-
I've a draggable bar, which can be drag horizontally. What I want to do is, on page scroll Is it possible to trigger draggable event to drag? Or is there any other way to achieve this. I already posted this question in StackOverflow but didn't get any response, So if someone could help me on this that would be appreciated.
-
Sorry for such a basic question. But it is a real problem. I am a GreenSock member and trying to load SlowMo for the first time and it just won't go. I've written basic code and loaded the proper CDNs <style> .box{width: 100px; height: 100px; border: solid 1px black;}</style> <body> <div class="box"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.7.1/gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.7.1/EasePack.min.js"></script> <script src="EasePack.min.js"></script> <script> gsap.to('.box', 3,{x: 1000, ease: "slow(.1, .7"}); </script> </body> I've loaded the EasePack.min.js file into my project: By all appearances (to me) this should do it. The code runs but does not include the SlowMo. A simple task for many, but I've spent a lot of time spinning my wheels on this and getting nowhere. Would someone please direct me as to where I am going wrong?
-
Hi, I've been using gsap and multiple plugins over the last couple weeks. For the most part I've found my way around but been stuck on this for the past day. The pen is a minimized version of what I'm trying to achieve, which is a pinned panel that rolls through 7 sections (all full-screen), and some of the panels have a lottie animation tied to it via ScrollTrigger. I got the panel to work, but tweaking timings is getting complicated, which I'm trying to solve via using a master timeline so the timings are contained. The timeline bit seems to work but I can't seem to get lottie to fire up correctly. Also any pointers on the rest of the code is appreciated as I'm sure there's a lot to be improved. Thanks in advance
- 9 replies
-
- scrolltrigger
- gsap
-
(and 1 more)
Tagged with:
-
In the given like you can see that the scroll animation gets stuck for ios. Working fine of android. Below is my code. Here is the site link : https://animationstest.vercel.app/work I am also attaching the video for your reference : useEffect(() => { gsap.registerPlugin(ScrollTrigger); const boxes = gsap.utils.toArray('.Work-info'); boxes.forEach(box => { gsap.from(box, { scrollTrigger: box, y: 100, duration: 1.2, opacity: 0, }); }); }, []);
-
Hi guys! I'm learning GSAP a few months, with the help of community, this is my first work using GSAP, in progress yet. Thanks all for help! And i have another question, about page transitions, shared element transitions between pages. See website reference at link: https://alfacharlie.co/ See the effect of transitions between pages, the softness the animations. I used the barba.js in html + css and it worked, but not working fine in wordpress, someone to help me achieve page transitions in wordpress site?
-
I want to use this parametric waves animation with gsap.min library, currently this is working with TwinMAX. After removing the gsap.min It's working fine but I cant remove gsap.min because other animations or not working without gsap.min I have getting the following error in console. Uncaught TypeError: Sine.easeInOut.getRatio is not a function https://codepen.io/ThiemelJiri/pen/pWyezW Anyone can help please? Thanks
-
Hello! I am trying to accomplish this effect https://greensock.com/docs/v2/Plugins/DirectionalRotationPlugin on a 3d scene. So basically i want the camera to transition to the point selected and not jump to it as it is right now. How can i do that?
- 3 replies
-
- three.js
- javascript
-
(and 2 more)
Tagged with:
-
Hello , i hope some one can help me , how i can do like this effect in gsap , not latterly same , but i want to open laptop win scroll , is there a way with gsap ? thank you in advance reference :https://www.apple.com/macbook-pro-13/ https://postimg.cc/ftRJTW5M
-
Hello Guys, I am having trouble creating an circular animation with motion path. Basically what I am trying to achieve is that all the 4 images rotate in even manner. for example First image should start from 0%, second from 25%, third from 50% and fourth from 75%. Here is the code sandbox for my code https://codesandbox.io/s/orbit-motion-path-mb6ns?file=/src/App.js:1339-1344 Please see attached screenshot for what I am trying to achieve Please help me. Thanks
- 2 replies
-
- motionpath
- motionpathplugin
-
(and 4 more)
Tagged with:
-
Hello guys, Im trying to build a simple carousel slider in vue 2. First problem is that my timeline is initially paused (i heard that is a good practice) and if i click next or prev button my animation doesn't play. I found solution, but I don't know if it is right one. I mean, it works but when using prevSlide function animation back to first initial slide. (probably thats another not related problem) So my question is how to handle timelines in vue. Should I put timeline in mounted, and prevSlide and nextSlide functions should only play or reverse the timeline? temporary solution: nextSlide() { this.tl.to(gsap.utils.toArray(this.$refs.slider.children), { xPercent: "-=" + 100, onComplete: this.tl.pause() }); this.tl.play() } the main code: <template> <div id="app"> <div class="slider" ref="slider"> <div class="slide"></div> <div class="slide"></div> <div class="slide"></div> </div> <button @click="prevSlide">prev</button> <button @click="nextSlide">next</button> </div> </template> <script> import gsap from "gsap"; export default { name: "App", data() { return { currSlide: 1, tl: gsap.timeline({ paused: true }), }; }, methods: { nextSlide() { this.tl.to(gsap.utils.toArray(this.$refs.slider.children), { xPercent: "-=" + 100, }); }, prevSlide() { this.tl.to(gsap.utils.toArray(this.$refs.slider.children), { xPercent: "-=" - 100, }); }, }, mounted() {}, }; </script> <style> #app { font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } .slider { width: 600px; height: 350px; display: flex; flex-direction: row; overflow: hidden; } .slide { width: 100%; height: 100%; flex-shrink: 0; } .slide:nth-child(1) { background: crimson; } .slide:nth-child(2) { background: green; } .slide:nth-child(3) { background: darkcyan; } </style> Code playground down below https://codesandbox.io/s/gracious-fog-y4b8d?file=/src/App.vue
-
React has updated and introduced hooks since this article was written. We recommend reading our updated guide to animating with GSAP in React. This page was also created for GSAP version 2. We have since released GSAP 3 with many improvements. While it is backward compatible with most GSAP 2 features, some parts may need to be updated to work properly. Please see the GSAP 3 release notes for details Preface This guide assumes a basic knowledge of both the GreenSock Animation Platform (GSAP) and React, as well as some common tools used to develop a React app. As GSAP becomes the de-facto standard for creating rich animations and UI's on the web, developers must learn how to integrate it with other tools like React which has become popular because it allows developers to write their apps in a modular, declarative and re-usable fashion. As a moderator in the GreenSock forums, I've noticed that there are a few common hurdles to getting the two working together seamlessly, like referencing the DOM element appropriately, doing things The React Way, etc. which is why I'm writing this article. We won't delve into how a React app should be structured since our focus is on using GSAP, but the techniques used throughout this guide follow the official guidelines and have been reviewed by maintainers of the React Transition Group tool. We'll start simple and get more complex toward the end. How GSAP Works GSAP basically updates numeric properties of an object many times per second which creates the illusion of animation. For DOM elements, GSAP updates the the inline style properties. const myElement = document.getElementById("my-element"); TweenLite.to(myElement, 1, {width: 100, backgroundColor: "red"}); As you can see this means that we need access to the actual DOM node rendered in the document in order to pass it to the TweenLite.to() method. How React Works Explaining how React works is beyond the scope of this article, but let's focus on how React gets the JSX code we write and puts that in the DOM. <div className="my-class"> Some content here </div> With React, we normally don't pass an id attribute to the element because we use a declarative way to access methods, instances, props and state. It's through the component's (or the application's) state that we can change how things are represented in the DOM. There's no direct DOM manipulation, so typically there's no need to actually access the DOM. The React team has given developers ways to access the DOM nodes when needed, and the API changed a bit over the years as React matured. At this time (September, 2018) the latest version of React (16.4.2) allows developers to use Refs to access the DOM nodes. In this guide we'll mainly use the Callback Refs to create a reference to the DOM node and then feed it into GSAP animations because it's much faster for GSAP to directly manipulate properties rather than funneling them through React's state machine. Creating Our First Animation We'll use the ref to access the DOM node and the componentDidMount() lifecycle method of the component to create our first animation, because this will guarantee that the node has been added to the DOM tree and is ready to be passed into a GSAP animation. class MyComponent extends Component { constructor(props){ super(props); // reference to the DOM node this.myElement = null; // reference to the animation this.myTween = null; } componentDidMount(){ // use the node ref to create the animation this.myTween = TweenLite.to(this.myElement, 1, {x: 100, y: 100}); } render(){ return <div ref={div => this.myElement = div} />; } } Not that difficult, right? Let's go through the code so we can understand what is happening. First when we create an instance of this class, two properties are added to it: myElement and myTween, but both are equal to null. Why? Because at this point the node has not been added to the DOM tree and if we try to pass this node to a GSAP animation, we'll get an error indicating that GSAP cannot tween a null target. After the new instance has been initialized, the render() method runs. In the render method we're using the ref attribute that is basically a function that has a single parameter – the DOM node being added to the DOM tree. At this point we update the reference to the DOM node created in the class constructor. After that, this reference is no longer null and can be used anywhere we need it in our component. Finally, the componentDidMount() method runs and updates the reference to myTween with a TweenLite tween whose target is the internal reference to the DOM node that should animate. Simple, elegant and very React-way of us! It is worth mentioning that we could have created a one-run-animation by not creating a reference to the TweenLite tween in the constructor method. We could have just created a tween in the componentDidMount method and it would run immediately, like this: componentDidMount(){ TweenLite.to(this.myElement, 1, {x: 100, y: 100}); } The main benefit of storing a TweenLite tween as a reference in the component, is that this pattern allows us to use any of the methods GSAP has to offer like: play(), pause(), reverse(), restart(), seek(), change the speed (timeScale), etc., to get full control of the animations. Also this approach allows us to create any GSAP animation (TweenLite, TweenMax, TimelineLite, etc.) in the constructor. For example, we could use a timeline in order to create a complex animation: constructor(props){ super(props); this.myElement = null; this.myTween = TimelineLite({paused: true}); } componentDidMount(){ this.myTween .to(this.myElement, 0.5, {x: 100}) .to(this.myElement, 0.5, {y: 100, rotation: 180}) .play(); } With this approach we create a paused Timeline in the constructor and add the individual tweens using the shorthand methods. Since the Timeline was paused initially, we play it after adding all the tweens to it. We could also leave it paused and control it somewhere else in our app. The following example shows this technique: Simple Tween Demo Animating a Group of Elements One of the perks of using React is that allows us to add a group of elements using the array.map() method, which reduces the amount of HTML we have to write. This also can help us when creating an animation for all those elements. Let's say that you want to animate a group of elements onto the screen in a staggered fashion. It's simple: constructor(props){ super(props); this.myTween = new TimelineLite({paused: true}); this.myElements = []; } componentDidMount(){ this.myTween.staggerTo(this.myElements, 0.5, {y: 0, autoAlpha: 1}, 0.1); } render(){ return <div> <ul> {elementsArray.map((element, index) => <li key={element.id} ref={li => this.myElements[index] = li} > {element.name} </li>)} </ul> </div>; } This looks a bit more complex but we're using the same pattern to access each DOM node. The only difference is that instead of using a single reference for each element, we add each element to an array. In the componentDidMount() method we use TimelineLite.staggerTo() and GSAP does its magic to create a staggered animation! Multiple Elements Demo Creating a Complex Sequence We won't always get all the elements in an array so sometimes we might need to create a complex animation using different elements. Just like in the first example we store a reference in the constructor for each element and create our timeline in the componentDidMount() method: Timeline Sequence Demo Note how in this example we use a combination of methods. Most of the elements are stored as an instance property using this.element = null, but also we're adding a group of elements using an array.map(). Instead of using the map() callback to create tweens in the timeline (which is completely possible), we're adding them to an array that is passed in the staggerFrom() method to create the stagger effect. Animating Via State The most commonly used pattern to update a React app is through changing the state of its components. So it's easy to control when and how elements are animated based on the app state. It's not very difficult to listen to state changes and control a GSAP animation depending on state, using the componentDidUpdate() lifecycle method. Basically we compare the value of a state property before the update and after the update, and control the animation accordingly. componentDidUpdate(prevProps, prevState) { if (prevState.play !== this.state.play) { this.myTween.play(); } } Control Through State Demo In this example we compare the value of different state properties (one for each control method implemented in the component) to control the animation as those values are updated. It's important to notice that this example is a bit convoluted for doing something that can be achieved by calling a method directly in an event handler (such as onClick). The main idea is to show the proper way of controlling things through the state. A cleaner and simpler way to control an animation is by passing a prop from a parent component or through an app state store such as Redux or MobX. This modal samples does exactly that: // parent component <ModalComponent visible={this.state.modalVisible} close={this.setModalVisible.bind(null, false)} /> // ModalComponent constructor(props){ super(props); this.modalTween = new TimelineLite({ paused: true }); } componentDidMount() { this.modalTween .to(this.modalWrap, 0.01, { autoAlpha: 1 }) .to(this.modalDialog, 0.25, { y: 50, autoAlpha: 1 }, 0) .reversed(true) .paused(false); } componentDidUpdate(){ this.modalTween.reversed(!this.props.visible); } As you can see the modal animation is controlled by updating the visible prop passed by its parent, as well as a close method passed as a prop. This code is far simpler and reduces the chance of error. State Modal Demo Using React Transition Group React Transition Group(RTG) is a great tool that allows another level of control when animating an element in a React app. This is referred to as the capacity to mount and unmount either the element being animated or an entire component. This might not seem like much when animating a single image or a div, but this could mean a significant performance enhancement in our app in some cases. SIMPLE TRANSITION DEMO In this example the <Transition> component wraps the element we want to animate. This element remains unmounted while it's show prop is false. When the value changes to true, it is mounted and then the animation starts. Then when the prop is set to false again, another animation starts and when this is completed it can also use the <Transition> component to wrap the entire component. RTG also provides the <TransitionGroup> component, which allows us to control a group of <Transition> components, in the same way a single <Transition> component allows to control the mounting and unmounting of a component. This is a good alternative for animating dynamic lists that could have elements added and/or removed, or lists based on data filtering. Transition Group Demo <Transition timeout={1000} mountOnEnter unmountOnExit in={show} addEndListener={(node, done) => { TweenLite.to(node, 0.35, { y: 0, autoAlpha: show ? 1 : 0, onComplete: done, delay: !show ? 0 : card.init ? props.index * 0.15 : 0 }); }} > In this example we use the addEndListener() callback from the <Transition> component. This gives us two parameters, the node element being added in the DOM tree and the done callback, which allows to control the inner state of the <Transition> component as the element is mounted and unmounted. The entire animation is controlled by the in prop, which triggers the addEndListener() and ultimately the animation. You may notice that we're not creating two different animations for the enter/exit state of the component. We create a single animation that uses the same DOM node and the same properties. By doing this, GSAP's overwrite manager kills any existing animation affecting the same element and properties, giving us a seamless transition between the enter and exit animations. Finally, using RTG allows us for a more fine-grained code, because we can use all the event callbacks provided by GSAP (onStart, onUpdate, onComplete, onReverse, onReverseComplete) to run all the code we want, before calling the done callback (is extremely important to notify that the animation has completed). Animating Route Changes Routing is one of the most common scenarios in a React app. Route changes in a React app means that an entirely different view is rendered depending on the path in the browser's address bar which is the most common pattern to render a completely different component in a route change. Obviously animating those changes gives a very professional look and feel to our React apps. Rendering a new component based on a route change means that the component of the previous route is unmounted and the one for the next route is mounted. We already covered animating components animations tied to mount/unmount using the <Transition> component from RTG, so this is a very good option to animate route changes. <BrowserRouter> <div> <Route path="/" exact> { ({ match }) => <Home show={match !== null} /> } </Route> <Route path="/services"> { ({ match }) => <Services show={match !== null} /> } </Route> <Route path="/contact"> { ({ match }) => <Contact show={match !== null} /> } </Route> </div> </BrowserRouter> This main component uses React Router's <BrowserRouter> and <Route> and checks the match object passed as a prop to every <Route> component, while returning the component that should be rendered for each URL. Also we pass the show property to each component, in the same way we did in the transition example. <Transition unmountOnExit in={props.show} timeout={1000} onEnter={node => TweenLite.set(node, startState)} addEndListener={ (node, done) => { TweenLite.to(node, 0.5, { autoAlpha: props.show ? 1 : 0, y: props.show ? 0 : 50, onComplete: done }); }} > As you can see, the code is basically the same used to animate a single component; the only difference is that now we have two animations happening in different components at the same time. Route Animation Demo It's worth noting that the animations used in this example are quite simple but you can use any type of animation even complex, nested animations. As you can see by now, using GSAP and React can play together nicely. With all the tools and plugins GSAP has to offer the sky is the limit for creating compelling and amazing React applications! FAQ What is this "Virtual DOM" thing, that is referred so much when it comes to React Apps? Can GSAP work with this virtual dom? The Virtual DOM is what React uses to update the DOM in a fast and efficient way. In order to learn more about it check this article and the React Docs. GSAP can't work with the virtual DOM because the elements in the Virtual DOM are not exactly DOM nodes per-se. I often read about the declarative nature of React. Does that affect how we use GSAP in a React APP? Yes. React works by updating the rendered DOM through changes in the App state, so when creating an animation using GSAP, instead of reaching out directly to the DOM, like in most other cases, we need to wait for those changes in the app state and the DOM to be rendered, in order to use the current representation of the app state and create the animation. To learn more about how declarative and imperative code work read this article. In the second sample I see this code in the ref callback ref={div => this.cards = div}. Why is the index being used instead of just pushing the element in the array? The reason for that is that every time a React component is re-rendered, the render method is executed, but the original instance remains unchanged. The array used to create the animation is created in the component's constructor. The GSAP animation (a TimelineLite) is created in the componentDidMount hook. These two elements are created just once in the App's lifecycle, while the render method is executed on every re-render. Therefore if we push the elements to the array on every re-render, even though the Timeline instance won't change, the array will get bigger and bigger every time the component is re-rendered. This could cause a memory issue, especially for large collections. In the guide one of the samples triggers animations via the state of a component or the app. Is it possible to update the state of the component/app using GSAP? Absolutely! All you have to do is use one of the many callback events GSAP has to offer. The only precaution is to be aware of infinite loops. That is if an animation is started on the render method of a component and a callback from that animation updates the state of the component then that will trigger a re-render, which will start the animation again. You can check this simple example of how that can be done. Is it possible to trigger a route change using GSAP? It is possible using React Router's API. Although is not recommended because using React Router's API directly will prevent triggering the route change animations when using the browser's back and forward buttons. However, using React Transition Group with GSAP does trigger the route change animations with the native navigation methods. Can I use other GSAP plugins and tools in a React App? This guide shows only TweenMax, Timeline and the CSS Plugin? Yes, any GSAP tool or plugin you want can be used in a React app. Just be sure to follow the same patterns and guidelines from this article and you'll be fine. I tried the code in the guide and samples, but it doesn't work. What can I do? Head to the GreenSock forums where all your questions will be answered as fast as possible. I want to contribute or post an issue to this guide. Where can I do that? Even though this guide was reviewed by GreenSock and React experts, perhaps something might have slipped away, or with time and new versions, some things should or could be done differently. For those cases please head to this GitHub Repo and inform any issues or create a Pull Request with the changes you think should be added. New to GSAP? Check out the Getting Started Guide. Got questions? Head over to the GreenSock forums where there's a fantastic community of animators. Acknowledgments I'd like to thank the three developers that took time from their work and lives to review this guide as well as the samples in it. I couldn't have done this without their help and valuable input. Please be sure to follow them: Xiaoyan Wang: A very talented React developer. While Xiaoyan doesn't have a very active online social life (Twitter, Facebook, etc), you can follow what he does on GitHub. Jason Quense: One of the maintainers of React Transition Group and part of the React Bootstrap Team. Jason also collaborates in many other React-related projects. Check Jason's GitHub profile for more info. Matija Marohnić: The most active contributor and maintainer of React Transition Group and Part of the Yeoman Team. Matija also contributes in a lot of React-related projects as well as many other open source software. Be sure to follow Matija in GitHub and Twitter. A guest post from Rodrigo Hernando, a talented animator/developer who has years of experience solving animation challenges. Rodrigo is a seasoned React developer and he was one of our first moderators, serving the GreenSock community since 2011 with his expert help and friendly charm.
-
- transitiongroup
- guest post
-
(and 4 more)
Tagged with:
-
Hello Dear members of this forum can i please ask for a little guidance. I want to combine three.js and gsap/scrollTrigger. My page structure is simple: two sections both with height: 100vh First section is simple hero baner that is not containing any animation (not relevant for the issue) and the second section is a place when magic should happen. I animating three.js model as soon as the second section hits the viewport and I did it by absolute postioning inside relative parent, creating a timeline with all the changes to model (rotation, scale, lighting, camera movment) and connect it all with scroll trigger (using "pin" propery) and this works like charm. Since I cant use codepen i will paste code here (so sorry) js: const timeline = gsap.timeline({ scrollTrigger: { trigger: ".scene-wrapper", start: "top", scrub: 1, pin: true } }); timeline .to(ambientLight, {intensity: 4, duration: 0.4}, 'scene1') .to(mainLight, {intensity: 5, duration: 0.4}, 'scene1') .to(model.rotation, {y: -Math.PI / 2, duration: 4}, 'scene2') .to(model.position, {x: 0, duration: 3}, 'scene2') .to(camera.position, {y: 0, duration: 3}, 'scene2') .to(camera.position, {z: 4, duration: 2.5}, 'scene3') .to(model.rotation, {z: -0.8, duration: 3}, 'scene3') .to(model.rotation, {y: -2.6, duration: 3}, 'scene3') .to(model.rotation, {z: 0, duration: 3}, 'scene4') .to(model.rotation, {y: -3.1, duration: 3}, 'scene4') .to(camera.position, {y: 0.4, duration: 3}, 'scene4') .to(camera.position, {z: 6, duration: 3}, 'scene4') html: <div class="wrapper"> <div class="section one"> <h1>Funny stuff</h1> </div> <div class="section two scene-wrapper"> <div class="background-container"> <div class="animation-container"></div> </div> <div class="scroll-container"> <section class="scene-1 scene"> <div class="copy-wrapper"> <h2 class="headline">This is 3D Model approach</h2> <p class="subtitle">Lorem ipsum dolor sit amet consectetur adipisicing elit</p> </div> </section> <section class="scene-2 scene"> <div class="content-column"> <div class="copy-wrapper"> <h2 class="headline">Scene 2</h2> <p class="subtitle">Lorem ipsum dolor sit amet consectetur adipisicing elit</p> </div> </div> <div class="content-column"> </div> </section> <section class="scene-3 scene"> <div class="copy-wrapper"> <div class="content-column"> </div> <div class="content-column"> <div class="copy-wrapper"> <h2 class="headline">Scene 3</h2> <p class="subtitle">Lorem ipsum dolor sit amet consectetur adipisicing elit</p> </div> </div> </div> </section> <section class="scene-4 scene"> <div class="copy-wrapper"> <h2 class="headline">Scene 4</h2> <p class="subtitle">Lorem ipsum dolor sit amet consectetur adipisicing elit</p> </div> </section> </div> </div> </div> As you can see inside ".scene-wrapper" i have container for aniamtion AND for 4 sections that i called scenes. My model is pined to a container and stays always on top of the screen (thats desired behaviour) but now i want to hide ans show this 4 texts from the "scens" in particular moments of my aniamtion and I dont know how to approach this.... So question to you dear forum: 1. Should I add animations of each text to the created timeline and create even longer timeline that i have right now or create separate timeline for text ? 2. Do I need second scrollTrigger instance just for texts ? To give you an idea what I want to create please see screenshots NOTE: this is free model downloaded from Sketchfab
-
Hi all, Looking for a hand or some advice if possible. I've created this codepen (below) and it works well enough when you drag the content horizontally but I would also like to be able to scroll with the mouse through the content, very much like the functionality of this website - https://antoni.de/cases/ I'm fairly new to Javascript and certainly GSAP, so any input is much appreciated. Thanks Jon
-
I was hoping somebody might be able to help with a little GSAP issue I'm having 🤞 Essentially, on our site we have a 'Menu and Search' button, that when clicked, will animate in the various parts of the full-screen, takeover menu. As well as this, we also have a separate function which deals with toggling a few classes, etc. This function has been assigned to the onStart callback, and also the onReverseCompleted callback, however it appears that on rare occasions (and I can't seem to create a consistent test case for this) that the onStart is running twice, and therefore breaks our animation. Does anybody have any ideas as to why this may be? I've mocked up a sample CodePen with a general gist of our code, except in a more simple context. Any help would be much appreciated. Thanks!
-
Hi, let me start by saying i love gsap and the hard work you guys put in it, since thats out of the way as you can see in my code pen i have two problems i need to solve. 1. When i drag and click on a card before inertia velocity go to zero the cards container animation position rest to x zero break. 2. When a crad onclick happens i want the animation drag to stop and when clicked again or a close button to reverse animation and rest where the card was. I feel am close but i need help 😅
-
Hey guys, I'm using SplitText plugin to show like a typing animation, the problem is that sometimes I have buttons inside the paragraph and the plugin is also typing those character when I don't need the text inside the buttons to have that animation. It's there a way to get avoid that text to be splited? I try several techniques, one was to remove the paragraph with the buttons outside of the SplitText animation, the problem there is that I need the movement to the next line
-
Hello to all. Maybe someone has time to review and correct the script - https://codepen.io/tester_info/pen/JjNJLNV Here is a small problem, it’s incorrect scrolling and changing the directions of the scrolling (from horizontal scrolling to vertical one and vice versa). There are two problems: 1. There is a bug in the scrolling (as I understand it’s because of the vertical block takes height, such as in horizontal). 2. The last section of the "contact block" cannot be scrolled to its full width Maybe we can work differently to perform this task with mix (horizontal/vertical) scrolling sections?
- 3 replies
-
- gsap
- timelinemax
-
(and 1 more)
Tagged with: