Jump to content
Search Community

Search the Community

Showing results for 'resize' in content posted in GSAP.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

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

Product Groups

  • Club GreenSock
  • TransformManager
  • Supercharge

Categories

There are no results to display.


Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Personal Website


Twitter


CodePen


Company Website


Location


Interests

Found 2,314 results

  1. Hi @Rodrigo, Thank you for your response! Upon opening your Codepen link in a maximized browser and then clicking on "Restore down" (essentially reducing the browser size), I noticed a significant padding on the right side of the page. I'm encountering a similar issue where the "scroller" length seems to be inconsistent, either too long or too short on a window resize.
  2. Hi, I'm a bit rusty with gsap, and need some help. I did a bit of vanilla js to pin a div for a moment, and it's working fine, (even though sometime it's a bit laggy on the first scroll) but since I'm using gsap and scroll trigger for something else on the same page, I though it would be better to use it too here, but I'm not sure how to do it. The pinned div has an absolute position, with a 50% top and transform translateY -50%, and when you scroll it push is it down so it look fixed. The cover_parallax div has a 200vh Height, so when it's scrolled to the bottom of the warper it stop. here is the code : window.addEventListener('scroll', checkContainerVisibility); ////////////////////// function toggleFixed() { isFixed = !isFixed; if (isFixed) { // Set initial position when becoming fixed updateFixedPosition(); window.addEventListener('scroll', updateFixedPosition); window.addEventListener('resize', updateFixedPosition); } else { // Clean up when no longer fixed window.removeEventListener('scroll', updateFixedPosition); window.removeEventListener('resize', updateFixedPosition); } } // Function to update the position of the fixed element based on scroll and resize function updateFixedPosition() { const scrollTop = window.pageYOffset || document.documentElement.scrollTop; // Adjust the top position of the fixed element content.style.top = `calc( 50% + ${scrollTop}px`; } function checkContainerVisibility() { var bounding = cover_parallax.getBoundingClientRect(); if ( bounding.bottom < 0 ) { cover_parallax.classList.add('annimeover'); } else { cover_parallax.classList.remove('annimeover'); } } How would you do the same with a gsap scroll trigger ?
  3. I have a project in Astro, and I'm using smooth scrolling and scroll trigger on various animations in different components of my homepage. However, animations that involve horizontal movements (I'm not sure if this is relevant or not) break when I resize the browser. Working code: <script type="module" is:inline> import gsap from "https://cdn.skypack.dev/gsap"; import ScrollTrigger from "https://cdn.skypack.dev/gsap/ScrollTrigger"; document.addEventListener("astro:page-load", () => { gsap.registerPlugin(ScrollTrigger); // Banner index animation const items = document.querySelectorAll(".sections ul li"); items.forEach((item) => { gsap.fromTo( item, { opacity: 0, y: 100 }, { opacity: 1, y: 0, ease: "power1.out", scrollTrigger: { trigger: item, start: "top bottom", end: "bottom-=100px bottom", scrub: 2, }, } ); }); }); </script> And this animations breaks on resize and kills any animation below him: <script type="module" is:inline> import gsap from "https://cdn.skypack.dev/gsap"; import SplitText from "../../node_modules/gsap/SplitText.js"; import ScrollTrigger from "../../node_modules/gsap/ScrollTrigger.js"; document.addEventListener("astro:page-load", () => { gsap.registerPlugin(ScrollTrigger, SplitText); function animation() { // Dividir el texto en líneas y aplicar una clase a cada línea const splitText = new SplitText("#highlightText .text", { type: "lines", linesClass: "lineClass", }); const splitTextClone = new SplitText("#highlightText .text.--clone", { type: "lines", linesClass: "lineClassClone", }); const container = document.querySelector( "#highlightText .js-text-animated" ); gsap.utils .toArray("#highlightText .lineClassClone", container) .forEach((line) => { const childLine = line.querySelector("#highlightText .lineClass"); // Definimos la animación con ScrollTrigger gsap.fromTo( line, { x: -line.offsetWidth }, { x: 0, ease: "power3.out", scrollTrigger: { trigger: line, start: "top bottom", end: "top top", scrub: 2, }, } ); // Animación para el hijo en dirección opuesta gsap.fromTo( childLine, { x: childLine.offsetWidth }, { x: 0, ease: "power3.out", scrollTrigger: { trigger: line, start: "top bottom", end: "top top", scrub: 2, }, } ); }); // Configuración de ScrollTrigger para separator-main gsap.to("#highlightText .js-section-separator-main", { x: -1000, // Cambiar según la distancia deseada scrollTrigger: { trigger: ".js-section-separator", start: "top bottom", end: "bottom top", ease: "power1.out", scrub: 2, }, }); // Configuración de ScrollTrigger para separator-secondary gsap.to("#highlightText .js-section-separator-secondary", { x: -1000, scrollTrigger: { trigger: ".js-section-separator", start: "top bottom", end: "bottom top", ease: "power1.out", scrub: 2.5, }, }); } animation(); }); </script> Thank you in advance!!
  4. I've run into an issue where ScrollTrigger freezes at a frame. If I keep resizing it back and forth it seems to come back to life. I don't seem to be getting any errors logged or anything. Below is the gsap snippet of the code running this part of the code. If anyone has any ideas!
  5. Hi I'm quite new to GSAP and having an issue I can't figure out. I have full width section that pins when it gets to the top of the window, then inside that section I have scrolltrigger which toggles the class on some tab sections to open them as you scroll. This works well until the browser is resized, then the markers for the tabs jump to the top of the page and therefore aren't being triggered any more. You can see it on the lower green section of my dev site https://avidd2024.dev.avidd-design.co.uk if (window.innerWidth > 640) { // Pin the tabs container when a tab title is active const tabsContainer = document.getElementById("pintrigger"); gsap.to(tabsContainer, { scrollTrigger: { trigger: tabsContainer, start: 'top 0', // When to start pinning at the top of the screen end: '+=1000', // Unpin after scrolling 1000px past the start pin: true, // Pin the element pinSpacing: true, // Maintain the pinned element's position invalidateOnRefresh: true } }); } // Loop through each tab title and define ScrollTrigger const tabTitles = document.querySelectorAll(".vertical .tabs-title"); tabTitles.forEach((tabTitle, index) => { gsap.to(tabTitle, { scrollTrigger: { trigger: tabTitle, start: "top top", // Start when top of tab title reaches top of screen end: "bottom top", // End when bottom of tab title reaches top of screen scrub: true, invalidateOnRefresh: true, toggleClass: { targets: tabTitle, className: "is-active" }, onToggle: (self) => { const panelId = tabTitle.querySelector('a').getAttribute('href'); const panel = document.querySelector(panelId); } } }); }); <section class="primary-color full-width" > <div class="block-tab-container" id="pintrigger"> <?php if (have_rows('repeater_content_tab')) { $counter = 0; ?> <ul class="tabs vertical" data-responsive-accordion-tabs="small-accordion medium-tabs" data-multi-expand="true" id="<?php echo esc_attr($id); ?>"> <?php while (have_rows('repeater_content_tab')) { the_row(); $tab_heading = get_sub_field('tab_heading'); $counter++; ?> <li class="tabs-title"> <a href="#tab<?php echo $counter?>-<?php echo esc_attr($id); ?>" aria-selected="true"> <div class="tabs-title-container"> <div class="text"><?php echo $tab_heading ?></div> </div> </a> </li> <?php } ?> </ul> <?php $counter = 0; ?> </div> <div class="tabs-content secondary vertical" data-tabs-content="<?php echo esc_attr($id); ?>"> <?php while (have_rows('repeater_content_tab')) { the_row(); $tab_content = get_sub_field('tab_content'); $counter++; ?> <div class="tabs-panel" id="tab<?php echo $counter?>-<?php echo esc_attr($id); ?>"> <?php echo $tab_content ?> </div> <?php } ?> </div> <?php } ?> </div> </section>
  6. Hi @claraapta welcome to the forum! As with anything in GSAP everything starts with an animation, so if the animation is not working it will never work on scroll. For now I've disabled ScrollTrigger in your demo, but be sure to enable it again when you think everything is correct. In the demo below we just get the total width of all the sections add together and use that as your x value. Bonus point for using a function based value https://gsap.com/docs/v3/GSAP/gsap.to()/#function-based-values so that it gets recalculated on resize. Hope it helps and happy tweening! https://codepen.io/mvaneijgen/pen/XWQLBzJ?editors=0010
  7. I see a lot of people hung up on creating buttons to scroll to a particular point on a page while using ScrollTrigger. Of course GSAP has you covered with this! See the ScrollTo plugin! But as with everything in GSAP it starts with an animation. First of please read my post about creating a stacking card effect, it will be used for the bases of this post So as usual everything in GSAP starts with an animation, so you first have to have an animation before you start doing anything on scroll, first focus on creating the animation you want to happen and when that is done we can worry about enhancing it with some scrolling https://codepen.io/mvaneijgen/pen/WNWqEYx If you’re happy with the animation you can add some ScrollTrigger logic to see how your animation works on scroll. https://codepen.io/mvaneijgen/pen/OJGevrB?editors=0010 Ok, now for the reason you’re here. How can we have a button that scrolls to a certain position on the page? That is where the ScrollTo plugin comes in, if you check the docs (https://gsap.com/docs/v3/Plugins/ScrollToPlugin/), the most simple setup is to just animate to a pixel value, let’s see how that works! The below example scrolls to 1000px, simple enough but I hope it illustrates what it is doing under the hood, because scrolling to a specific section will be nothing more than getting the pixel value you want to scroll to and using this as the value in the scrollTo: property! https://codepen.io/mvaneijgen/pen/JjVQOyK But now we want to scroll to the third card in the animation, how can we do this? We know the total scroll distance of the ScrollTrigger because we define that in the start and end properties, right now the ScrollTrigger starts on the top of the browser and has a distance of 4 times the current window height (end: `${window.innerHeight * 4} top`) and we have in total 4 animations! This means each slide animates over the hight of the window, so what do you think will happen if we animate to the current window hight times 2? Well let's see! https://codepen.io/mvaneijgen/pen/BaEgwoz It animates to the third slide! As you can see I’ve wrapped the code in an arrow function, this indicates to GSAP that we want to recalculate this value if ScrollTrigger.refresh() is triggered, which happens on a page resize, because when the page resized probably the height of the browser changes, so we need to get new values. If you do not use a function based value you indicate to GSAP that it should not recalculate it’s values and can use its cached values. If you want to read more please check out the docs https://gsap.com/docs/v3/GSAP/gsap.to()/#function-based-values Great we’re done! lets add some more content to the page and everything will be working just fine! But wait!? Why does it now only scroll to the second slide? Before it was scrolling to the third slide. Well all ScrollTrigger is doing is animating to a specific pixel value and because we’ve add another section before it, the scroll distance will be different. What you can do in this case is add the ScrollTrigger start value to the calculations, so instead of just animating to twice the window height, we animate to tl.scrollTrigger.start + window.innerHeight * 2, just try it your self and you’ll see it will always scroll to the top of the ScrollTrigger + twice the window height https://codepen.io/mvaneijgen/pen/BaEgwoz Ok, I hear you thinking, but I want to animate to each slide, and what if my scroll distance changes then I need to update my calculations every where! You are totally right! And the folks on the GSAP team has thought of everything! So what you can do is add labels to your timeline and then scroll to those labels! This can be as simple as scrolling to a specific label eg tl.scrollTrigger.labelToScroll("label3") or this can be be fancy like the example below by getting the next label in the timeline and scrolling to that, I hope you see that you can as easily scroll to the previous label. https://codepen.io/mvaneijgen/pen/gOyNeqj?editors=0010 If you don't have labels in your timeline you can also do some math to scroll to a specific point in a timeline. The progress of a timeline is always between 0 and 1, so what you can do is get the end and start values of you ScrollTrigger and then subtract and then multiply that by 0.5 to that the halfway point of the animation or any other value! Again to emphasise all ScrollTo need is a pixel value and it is up to you to get the correct value. GSAP gives you all the tools you need, but it is for you to figure out what the math is behind the logic you are looking for! Hope it helps and happy tweening!
  8. That is called Flash Of Unstyled content eg FOUC, check out this post https://gsap.com/resources/fouc/ Best is to have GSAP fire when everything has loaded especially images, fonts ect, because if you use ScrollTrigger the hight of everything is really important. Sadly we don't have the time and resources to provide free general consulting, but your code looks fine. I would not worry about it the only thing I can see is that you use x: "120%" and especially for percent based values we have xPercent: 120, same as x: `${distance}px`, I would write it like x: () => distance, this will get distance again if ScrollTrigger.refresh() is called (which happens on page resize) read more about function based values https://gsap.com/docs/v3/GSAP/gsap.to()/#function-based-values Hope it helps if you need further assistance, please provide a minimal demo, so that we can take a look at your code in action. Happy tweening!
  9. Hi GSAP community, Can anyone help me with the following issue? I'm using ScrollTrigger to horizontally scroll/pin a few slides. The number of pixels to scroll (x) is a dynamic value: the overflow of the row with slides compared to it's parent. This works perfectly on the initial load of the page. But if you resize the viewport to a point where the parent narrows the pin end point gets off. I made a minimal demo to reproduce the issue. Resize the window to a point where the parent/container (blue border) narrows. You'll see that the last slide (the end of the scrub) won't line up with the parent container (blue border) anymore. I assume my function to calculate the overflow is wrong. Any help is greatly appreciated!
  10. Hello GSAP Community! Thank you so much in advance for your help! I am trying to create a scaled animation on scroll. When user scroll down to section a box will appear from down to center and when it hits center of the screen then start to scale upto 1. It is working on reload window but when i resize window on this section, it suddenly beaks its scaled position. All your help is greatly appreciated!
  11. Hi everyone, Can anyone help me figure out on how to do this type of animation on scroll. It is a canvas with svg patterns, and when the user scrolls it will start scaling the 1st row from a smaller size to the initial svg width and height. Not sure how to make this one work Would really appreciate if someone can help me. I have had an attempt, maybe it is a good start but I can't figure it out properly. I have also break down the code into parts from the https://remote.com/global-hr/contractor-invoicing-and-payments https://i.imgur.com/hXHepSI.mp4 HTML <div class="sc-f1d6031c-0 hjWElG pattern-transition" from="white" to="red500"> <canvas width="5080" height="868"></canvas> <svg width="78" height="40" viewBox="0 0 78 40" xmlns="http://www.w3.org/2000/svg" class="pattern duo-petal pattern-ref" style="fill: pink;"> <path d="M39 39.9939C47.9212 39.939 60.9436 36.5061 67.7442 29.6951C74.3072 23.122 77.7258 14.2683 78 5.54268V0H76.507C66.495 0.195122 56.2148 2.82317 48.5672 10.4878C43.4911 15.5732 40.3162 21.8232 39 28.378C37.6838 21.8232 34.5089 15.5732 29.4328 10.4878C21.7852 2.82317 11.505 0.195122 1.49297 0H0V5.54878C0.280313 14.2744 3.69891 23.128 10.2558 29.7012C17.0564 36.5122 30.0727 39.9451 39 40"></path> </svg></div> CSS .hjWElG { position: relative; width: 100%; display: grid; margin-top: -0.5px; margin-bottom: -0.5px; background-color: #ffffff; } /*!sc*/ .hjWElG canvas { width: 100%; height: auto; } /*!sc*/ .hjWElG .pattern-ref { position: absolute; visibility: hidden; pointer-events: none; } document.addEventListener("DOMContentLoaded", function() { const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); const svgPath = document.querySelector('svg path').getAttribute('d'); const patternColor = 'pink'; // Color of the SVG fill let pattern; let maxScale = 1; // Maximum scale at the bottom of the page // Function to draw the SVG path into a canvas pattern function drawPattern(scale) { const scaledWidth = 78 * scale; const scaledHeight = 40 * scale; const blob = new Blob([`<svg xmlns='http://www.w3.org/2000/svg' width='${scaledWidth}' height='${scaledHeight}'><path fill='${patternColor}' d='${svgPath}' transform='scale(${scale})'/></svg>`], {type: 'image/svg+xml'}); const url = URL.createObjectURL(blob); const img = new Image(); img.onload = function() { pattern = ctx.createPattern(img, 'repeat'); updateCanvas(scale); URL.revokeObjectURL(url); }; img.src = url; } // Function to update canvas drawing based on scroll function updateCanvas(scale) { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = pattern; ctx.save(); ctx.scale(scale, scale); ctx.fillRect(0, 0, canvas.width / scale, canvas.height / scale); ctx.restore(); } // Update the canvas on scroll window.addEventListener('scroll', function() { const scrollPercent = window.scrollY / (document.body.scrollHeight - window.innerHeight); const scale = Math.max(scrollPercent, 0.1) * maxScale; // Scale starts from 0.1 to 1 drawPattern(scale); }); // Resize canvas dynamically and redraw pattern window.addEventListener('resize', function() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; const scale = window.scrollY / (document.body.scrollHeight - window.innerHeight) * maxScale; drawPattern(Math.max(scale, 0.1)); }); // Initial setup canvas.width = window.innerWidth; canvas.height = window.innerHeight; drawPattern(0.5); // Start with the smallest scale });
  12. Just so you know, you could just call tween.revert() instead of doing both kill() and clearProps. You could also record the progress in your resize handler, and then re-apply that to make things continuous: https://codepen.io/GreenSock/pen/ZEZNmpz?editors=0010
  13. I think you'd just need to clearProps when you resize and kill the tween. https://codepen.io/PointC/pen/bGJyjYz/03ab931389596f7fd6e582a8f9c6c1ec But I agree with @Trapti, there are easier ways to do this with an SVG. Happy tweening.
  14. @mvaneijgenThank u for the reply. I followed the points u mentioned and was finally able to solve the issue. I used timeline and used fromTo to state the intitial and final xPercent instead of using the transform in css. I guess css and gsap conflicted or something. Now it seems to maintain its position relative to its container even when i resize the window.
  15. @GSAP HelperI apologize. Now , I have included the codepen for the animation i wanted to implement. It works but when i resize the window , those green divs just seem to go out of the container(u can just resize this window). But when i refresh the page(or rerun the code) , the green div seems to be in correct place. Its kind of hard to explain whats happening. I hope the codepen gives some insight. The problem seems inconsistent too.
  16. Hello! In the codepen demo, I want the circle to orbit the rectangle. It works perfectly on page load. However, upon resize, despite killing the previous tween and creating a new one with updated values for the motionPath plugin, the circle moves in random directions instead of orbiting the rectangle. How can I make sure that the circle moves around the rectangle after resizing (just like how it works on page load)? PS - I encounter this console error post resize - "Unable to preventDefault inside passive event listener due to target being treated as passive." Could this relate to my issue? Thanks!
  17. Im new to the whole thing , and Im just learning about gsap. I tried to create sort of parallax like effect , where the parallaxRef elements(those logos) moves left or right when i scroll up or down. It basically moves those logos horizontally when i scroll. And it works as intended. For the first row of logos , I translate it -30% and using gsap and its scrollTrigger , I translate it to 30% so when i basically at the middle of the container , those logos are relatively at the middle of the container. But when i resize the window , their position just seems to be weird position as shown in picture 2. But when i reload the page , it goes back to its intended position. I dont know if i explained the problem properly. Im using REACT for this. If theres a better way of doing it , it would be awesome too. 1st pic shows the page before resizing the window. 2nd pic shows the page after resizing the window with the logo's position all messed up. 3rd pic is after reloading the page , which seems to correct their position. const parallaxRef = useRef(null); const parallaxRef2 = useRef(null); const setupParallaxTriggers = () => { gsap.to(parallaxRef.current, { xPercent: 30, scrollTrigger: { trigger: '.container', scrub: 1, start: 'top bottom', end: 'bottom top', invalidateOnRefresh: true, markers:true, }, }); gsap.to(parallaxRef2.current, { xPercent: -30, scrollTrigger: { trigger: '.container', scrub: 1, start: 'top bottom', end: 'bottom top', invalidateOnRefresh: true, markers:true, start: '40% bottom', }, }); }; useEffect(() => { setupParallaxTriggers(); }, []) return( <div style={{margin:'100rem 0rem'}}> <section className='container'> <h1>DEMO</h1> <div className='box' style={{transform:'translateX(-30%)'}} ref={parallaxRef}> <span className='level'> <p>Level</p> <p>Intermediate</p> </span> <div><img src={html} alt="html"/></div> <div><img src={css} alt="css"/></div> <div><img src={javascript} alt="js"/></div> <div><img src={react} alt="react"/></div> </div> <div className='box' style={{marginTop:'10rem',transform:'translateX(30%)'}} ref={parallaxRef2}> <div><img src={node} alt="node"/></div> <div><img src={express} alt="express"/></div> <div><img src={mongodb} alt="mongodb"/></div> <span className='level'> <p>Level:</p> <p>Beginner</p> </span> </div> </section> </div> ) } react (1) (1).mp4
  18. the thing is at start, before the animation starts, it don't resize, although the width is set to width: calc(100vw - 100px). I do need those widths: based on width at start AND 236px at the end… making the value change with scale would involve a formula based on the width of the screen which in the end should result in a value of 236px https://capture.dropbox.com/mpWJ5kxvlCb7CD2F
  19. one more thing, sorry… how do i resize the logo width with window resizing? I've set it to a portion of vw… and when i resize the window, the logo stays the same size
  20. I am trying a very simple animation of Gsap. With pin enabled. The design works perfectly in PC, and when open in Mobile, the pinned are jumps abnormally down, I tried increasing decreasing the star, end with all combinations, it only gets worse. Please help. I am describing the problem with screenshot below: I have actually Pinned the containing div of that h2 tab visible on screenshot, it goes up and in i have given the start as "0% 12%". First of all the marker should have been above the h2 tag, as I have given 0% but it's below the tag. And secondly after the marker reaches the start position, it suddenly makes a jump by coming down to the position in the following screenshot. I have also tried removing all the margins on the container and the container above, but still no luck. What is this problem? Someone please help me fix this. The Same Problem can also be seen in the codepen I have attached, Resize the screen to something near to 300px wide, and see how the h2 jumps place after getting pinned.
  21. Thanks for clarifying, I'll definitely be using this syntax in the future! If this isn't too far out of the scope of my initial issue, I managed to reproduce something I'm running into with these tweens. I have two instances of the same component (it's all in the demo) – one on the page and one inside a modal. For their timelines to run independently I need to declare them as Vue refs. Which is fine, except for some reason when the timeline is reset on reside, the timeline for the other instance of the component gets messed up. For example in this demo, scroll down to activate the on-page animation, resize it, scroll again to re-activate it, then toggle the modal. The modal splitText animation doesn't run correctly, probably because the split isn't properly recalculated. I suspect it's a vue-specific issue but if there's any way to negate it I'm all ears! Here's the demo: https://stackblitz.com/edit/nuxt-starter-zdudyt?file=app.vue,components%2FTextComponent.vue
  22. That's my fault, I tried to narrow down my issue as much as possible to simplify it and obviously the context was important! The real issue I'm having is actually related to splittext and resizing in Nuxt, and I'm unable to include splittext in a demo since it's a club plugin and I can't for the life of me figure out how to set up a nuxt environment in codepen. What I would like to do is this: 1. On resize, immediately reset the split to its original state so that the text resizes 'naturally'. 2. Debounce re-creating the timeline 3. Set the timeline's progress to 1 so the whole thing looks like it never happened. Then, when the user goes on their merry way interacting with this element, it animates as it's supposed to, having resized and done all its business. function createTimeline() { split = new SplitText('.text', { type: 'lines' }) timeline = gsap.timeline({ paused: true, defaults: { delay: 0.15 } }) .fromTo(split.lines, { y: '100%', x: 10, autoAlpha: 0, scale: 0.99 }, { duration: 1, y: 0, x: 0, autoAlpha: 1, scale: 1, stagger: 0.07, ease: 'power2.inOut' }) } function recreateTimeline() { createTimeline() timeline.progress(1) } const debounceHandler = debounce(recreateTimeline, 300) function handleResize() { if(timeline){ timeline.revert() split.revert() } debounceHandler() } onMounted(() => { window.addEventListener('resize', handleResize) }) What ACTUALLY happens is probably an issue with Nuxt more than anything (or maybe I'm missing something!), but it's the reason I thought I had to wait for .revert(). When I run handleResize(), the timeline and split are reverted and the debounceHandler is called just fine. The problem is that when recreateTimeline() calls createTimeline(), the split is not properly reverted and SplitText() runs on text that's already been split. Even though it should've been reset to its original state when handleResize() was first called. It's like the reverts never happened, or if they did they got stuck halfway. The timeline doesn't recreate properly and none of the animations run after resize. This does not happen if I debounce the entire handleResize function but I don't want to do that because when the user resizes the window down, they will see the incorrectly positioned text for 300ms or however long I set the debounce to. What I ended up having to do is this horrorshow: Basically I'm having to call the reset behavior multiple times to make sure it's cleaned up even though the reset DOES happen immediately, but for reasons I don't yet understand, not correctly or fully. let timeline let split function createTimeline() { split = new SplitText('.text', { type: 'lines' }) timeline = gsap.timeline({ paused: true, defaults: { delay: 0.15 } }) .fromTo(split.lines, { y: '100%', x: 10, autoAlpha: 0, scale: 0.99 }, { duration: 1, y: 0, x: 0, autoAlpha: 1, scale: 1, stagger: 0.07, ease: 'power2.inOut' }) } function destroyTimeline() { timeline?.revert() split?.revert() split = null timeline = null } function recreateTimeline() { destroyTimeline() nextTick(() => { createTimeline() timeline.progress(1) }) } const debounceTimeline = debounce(recreateTimeline, 300) function handleResize() { timeline?.revert() split?.revert() debounceTimeline() } onMounted(() => { window.addEventListener('resize', handleResize) }) If you're still reading by this point, I salute your immense patience. Basically I thought that MAYBE the issue was that reverts() weren't immediate, and I had to await them before running anything that relied on them being complete.
  23. Hi, I'm not 100% sure of what issue you're experiencing, but waiting for 1 tick of GSAP's ticker should be enough. As far as I can tell, after you revert your GSAP instances and create the new ones, it should take 1 tick to render the new ones, so that should be enough. Based on your demo this is how I would proceed: const tweenable = document.getElementById('tweenable') let tween, timer; const createTween = () => { tween = gsap.timeline().fromTo(tweenable, {opacity: 1}, {opacity: 0, duration: 1}); }; const revertTween = () => { tween && tween.revert(); createTween(); }; window.addEventListener("resize", () => { timer && clearTimeout(timer); timer = setTimeout(() => { revertTween(); }, 200); }); createTween(); Here is a fork of your demo: https://codepen.io/GreenSock/pen/oNOVzdg Hopefully this helps. Happy Tweening!
  24. Hi all, I'm working with SplitText and I need to be able to revert everything, reset timelines, and then recreate and re-run everything on resize. The main issue I'm having is chaining everything nicely. timeline.reverse() returns itself 'for easy chaining' according to the docs. Except you can't chain timeline.reverse().then() (this throws an error) and wrapping it in a promise doesn't work either. What is the best way to make sure everything has been fully reverted when wrapping reverts in external functions? Because if I dump everything into one function, things do get cleaned up correctly, but we obviously don't want to do that.
  25. Yeah, you could keep track of the state of one set of images and use Flip's fit() method: https://gsap.com/docs/v3/Plugins/Flip/static.fit() Also in order to keep things optimized you can check the state of the images only at startup and then on a window resize using a debounce method for that. Happy Tweening!
×
×
  • Create New...