Jump to content

Search In
  • More options...
Find results that contain...
Find results in...

Vlad Tw

  • Posts

  • Joined

  • Last visited

About Vlad Tw

Vlad Tw's Achievements

  1. I thought that too! Not to mention that the rendered image gets correctly assigned in DOM, before JS and gsap takes over: img[Attributes Style] { width: 717px; aspect-ratio: auto 717 / 947; height: 947px; } I'll investigate a bit more on this, but i think is all clear now from gsap's side. Thanks thanks a lot!
  2. Yup, that works @OSUblake! Can't even be happy at this point, but truly grateful. 💚 Is this a valid solution on a heavy-image website? (impact on performance)
  3. Thank you @Cassie, @OSUblake, @GreenSock, your help put an end to the mystery! Blake, the repo you provided truly has no issues and that threw me off, since our repos were almost identical, except few html elements. As i said, i did not managed to get a consistent solution for ScrollTrigger. I figured out why after reading this: https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-link/#handling-stale-client-side-pages. The Gatsby Link component has intelligent preloading, and i guess that some stale client side page data is conflicting with the real elements, when the page that contains the ScrollTrigger is first accessed using the link, and not the actual navigation to localhost:8000/about. index.js export default function Index() { return ( ... <Link to="/about" color="secondary"> Go to the about page </Link> ... ); } Now in order to reproduce the issue, just a small addition to your code. Please add the following somewhere in-between those grid items: aboutBlock.js <Grid item id="breaking" ref={addToRevealRefs} sx={{ "& img": { height: 'auto', width: '100%' } }}> <img width="717" height="947" src="https://bukk.it/%3F%3F%3F%3Fcone%3F%3F%3F%3F%3F%3F%3F%3F.jpg" alt="aa" /> </Grid> Then: I would recommend deleting .cache and public folders to make sure there are no leftovers run: gatsby develop open localhost:8000 CLICK on Go to about page link ScrollTrigger is broken 🙁 (Can be tested in production build aswell, with gatsby build then gatsby serve-> localhost:9000) I cannot say i know for sure why is this happening, but I identified two situations up until now: page contains images with css altered width/ height page contains textareas with number of rows > 1 ( I noticed that the SSR-ed page always contains 1 row textarea, the remaining rows being added dynamically by react, when js takes over) Now again, this is happening IF GatsbyLink is used. If we replace that one with regular a, everything works fine. ✔️ index.js export default function Index() { return ( ... <a href="/about" color="secondary"> Go to the about page </a> ... ); } Replacing Gatsby Link with regular a tag would be a sad compromise when using GSAP with Gatsby, since the speed of loading a page would be drastically decreased. I strongly hope there could be some twist to this. However, if this is a must, it should come to our attention, to not waste days mumbling in the dark. What do you guys think? *PS: thank you for reading this (again)! This forum does not cease to amaze me!
  4. Hi guys! I come humbly in front of you with few drops of hope left, after 5 full days of switching between possible solutions to get a consistent ScrollTrigger behavior on a Gatsby site. Getting directly to you is my last resort, as every google and gsap forum link regarding ScrollTrigger and Gatsby is already visited. 😒 I cannot get a CodePen reproducing the exact issue so I'll try my best to describe it here. Shortly, the problem seems to be, as I suspect, that the ScrollTrigger does not refresh itself when Javascript pops into the browser on top of the SSR-ed html/css bundle. Here's what i did. I created several projects with different versions for dependencies, but i will stick to the simplest one with all dependencies up to date.It's a gatsby with material-ui plugin added, who's exact structure can be found here: https://github.com/mui-org/material-ui/tree/master/examples/gatsby There are no other plugins added, nor any other configs/plugins changed. I rendered the component that will contain the ScrollTrigger (AboutBlock) in the AboutPage page: about.js const AboutPage = () => { return ( <AboutBlock /> ) } export default AboutPage This is the component where i try to animate some elements on reveal when scrolled into view: aboutBlock.js import gsap from "gsap"; import ScrollTrigger from 'gsap/ScrollTrigger'; import animateReveal from "./gs_reveal"; export default function AboutBlock() { gsap.registerPlugin(ScrollTrigger) const revealRefs = useRef([]) revealRefs.current = [] useLayoutEffect(() => { let scrollTriggers = [] scrollTriggers = animateReveal(revealRefs.current) return () => { scrollTriggers.forEach(t => t.kill(true)) } }, []); const addToRevealRefs = el => { if (el && !revealRefs.current.includes(el)) { revealRefs.current.push(el); } }; return ( <Grid container> <Grid item width={{ xs: '100%', sm: '80%', md: '35%' }} pl={{ xs: 0, md: '2.5%' }} mt={{ xs: 60, sm: 0 }}> <Grid container direction="column" alignItems={{ xs: "flex-start", sm: "flex-end" }}> <Grid item mt={{ xs: 0, md: '10vh' }} id="acum"> <Typography variant="h5" textAlign={{ xs: "left", sm: "right" }} ref={addToRevealRefs} className='gs_reveal_fromRight'> NOW WE ARE IN </Typography> </Grid> <Grid item> <Typography variant="h6" textAlign={{ xs: "left", sm: "right" }} ref={addToRevealRefs} className='gs_reveal_fromRight'> LOCATION </Typography> </Grid> <Grid item mt="10vh" id="hi"> <Typography variant="h5" textAlign={{ xs: "left", sm: "right" }} ref={addToRevealRefs} className='gs_reveal_fromRight'> SAY HI </Typography> </Grid> <Grid item className='toughts'> <Typography variant="h6" textAlign={{ xs: "left", sm: "right" }} ref={addToRevealRefs} className='gs_reveal_fromRight'> TELL US YOUR THOUGHTS </Typography> </Grid> </Grid> </Grid> </Grid> } HTML is longer and crowded, I left a part to get the idea of the structure and styling approach (MUI's sx - emotion). And finally, this is the animateReveal function: gs_reveal.js import ScrollTrigger from 'gsap/ScrollTrigger'; import gsap from 'gsap'; export default function animateReveal(elements) { const triggers = [] elements.forEach(function (elem) { hide(elem) let tr = ScrollTrigger.create({ trigger: elem, id: elem.id, end: 'bottom top', markers: true, onEnter: function () { animateFrom(elem) }, onEnterBack: function () { animateFrom(elem, -1) }, onLeave: function () { hide(elem) } }); triggers.push(tr) }); return triggers; } function animateFrom(elem, direction) { direction = direction || 1; let x = 0, y = direction * 100; if (elem.classList.contains("gs_reveal_fromLeft")) { x = -100; y = 0; } else if (elem.classList.contains("gs_reveal_fromRight")) { x = 100; y = 0; } else if (elem.classList.contains("gs_reveal_fromBelow")) { y = -100 } elem.style.transform = "translate(" + x + "px, " + y + "px)"; elem.style.opacity = "0"; gsap.fromTo(elem, { x: x, y: y, autoAlpha: 0 }, { duration: 1.25, x: 0, y: 0, autoAlpha: 1, ease: "expo", overwrite: "auto", delay: elem.classList.contains("gs_delay") ? 0.3 : 0, }); } function hide(elem) { gsap.set(elem, { autoAlpha: 0 }); } The ScrollTrigger markers are misplaced when page loads, and might move (get more misplaced) on hard reloading page, depending on the current scroll position in the moment of reloading, even though the scroll position is not preserved on reload (always is scrolled on top). - The markers are placed on the correct position on resizing, as expected. I followed gsap official docs on react and react-advanced and tried: grabbing the html elements to animate on scroll inside animateReveal() by let elements = gsap.utils.toArray(".gs_reveal"); Assigning to each element a useRef() and use the .current value for each in animateReveal() grabbing html elements using gsap's selector utility gsap.utils.selector changing to simpler animation on scroll, like just a fade refreshing ScrollTrigger in different moments useLayoutEffect(() => { ScrollTrigger.refresh(true) // or ScrollTrigger.refresh() ... }, []); 6. Lifting ScrollTrigger logic to parent about.js page 7. Assigning scrollTrigger to a timeline triggered by the to-be-reveal element 8. Use useEffect() instead of useLayoutEffect() (recommended anyway for ScrollTrigger) 7. Other who-knows-what unsuccessful twists. I suspected a rehydration error, when the static generated code does not match the client side one. But the only JS that could cause a mismatch is the gsap related one, and it does not seem an SSR issue. I checked if the CSS and HTML elements are being properly SSR-ed, by preventing JS from running in the browser. All looking fine. This is both a SSR issue (gatsby build) and a development issue (no SSR). As i said on point 5, setting a ScrollTrigger.refresh() when component is mounted does not work, but delaying this with a 1-2 seconds in a setTimeout successfully solves the issue useLayoutEffect(() => { setTimeout(() => { ScrollTrigger.refresh(true) }, 2000); }, []); This is hard to be accepted as a solution, since i cannot rely on a fixed value to 'guess' when DOM is properly rendered in the eyes of the ScrollTrigger, not to mention the glitches that might occur. So, the question is 'WHY?', why animating with ScrollTrigger from within useLayoutEffect, which is not triggered on the server anyway and should mark the 'component is successfully mounted' moment, seems to not wait for the DOM being completely painted, even though nothing is generated dynamically! There are quite of threads on this forum regarding gatsby, and none seemed to have a clear cause-outcome-solution. Is this battle lost, should i move on? Do you have any suggestions? Thanks so much for your time reading this, it means so much to me!
  5. I'm trying to stop the animation of the bouncing ball with the ball at somewhere 50% done of the final iteration. Meaning, the ball should end up being 'in the air', not on the floor. I can't find a way to target specifically the final repetition. Can this be done with some adjustment to this timeline, or another one should be created to move the ball when bouncing timeline ends? Thank you for your time!
  6. Exactly what i was looking for! You're a life saver. Thanks a lot 💚
  7. Hi Cassie, thank you for your time! That's a nice point you have there. I 'learn' from so many places outside gsap, and the more i learned, the more i felt the need to learn. I got addicted to learning and that turned out not to be the most proficient way of moving forward. I switched a bit to be addicted to acting and then asking for feedback. This codepen seemed the right approach for me and i chose it as the way to implement such a reveal-on-scroll on a website, and i was hoping there is some small adjustment i could make to the current architecture to obtain the stagger effect. If however you think there is a better approach to obtain a similar centralized solution to handle such a reveal on scroll, please let me know. Again, thank you so much!
  8. Hi guys, hope you're having an amazing day! Mine not so much, as a gsap beginner. 🙄 I'm trying to add a stagger to the reveal animations of the elements that are positioned on the same level in the page ( y axis). More precisely, i want to add some delay between revealing the image and it's corresponding text. Any suggestions will help. Thank you!
  9. Vlad Tw

    DNA animation

    Hi guys! This is my first time reaching on GSAP forum, so i apologize in advance if my question does not fit certain criteria. Do you have any tips on how can one approach an animation similar to the one on https://www.aeratechnology.com/? (the slowly moving dna on top center of the page). It comes hard for me to believe that there are 3 different shapes, just rotating, especially the striped one). Any codepen or gsap feature that i can harness will help, as i was not able to get anything of the big picture that should be in my head. Thanks a lot.