Jump to content
Search Community

purple-lightsaber

Members
  • Posts

    21
  • Joined

  • Last visited

Posts posted by purple-lightsaber

  1. @Rodrigo thanks for the input, I've tried copying what the other block is doing but it seems to break it completely. The code does execute in normal Chrome, but yes for some reason it doesn't seem to fire in Safari or incognito. 

     

    Also I was calling it twice to ensure it fires and hard refreshes, since that was giving me issues as well. I will try removing one though. 

     

    Thank you

  2. This is a Webflow site, so because there is a 10k character limit on svg code I have a workaround to fetch the SVG from a link. 

    The async function animateSVG() is the one not working, but the footer SVG "async function animateFooterSVG()" is working on both Incognito Chrome and Safari. 


    There is also a bug on each animation if you scroll down really fast, the hero SVG appears after fading out, and the footer SVG pops up without doing its draw in animation.

    Any feedback is appreciated!

    Website:
    https://captivate-hr.webflow.io/

     

    You can see the JS/ CSS code in Webflow by clicking the link below, hitting "P", clicking on the gear icon next to "Home", and scrolling down to the code:
    https://preview.webflow.com/preview/captivate-hr?utm_medium=preview_link&utm_source=dashboard&utm_content=captivate-hr&preview=1cd5250b9c4cae29b70966c031419a96&workflow=preview

     

     

    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/ScrollTrigger.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/ScrollToPlugin.min.js"></script>
     
    <script>
    // Configuration variables
    const fadeInViewportOffset = 0.31; // Change this to control the viewport offset for fading in (0.5 = center)
    const fadeOutViewportOffset = 0.67; // Change this to control the viewport offset for fading out (0 = top)
     
    gsap.registerPlugin(ScrollTrigger);
     
    // Animation setup
    document.querySelectorAll(".scroll-component").forEach((scrollComponent) => {
      // Set the initial opacity to 0
      gsap.set(scrollComponent, { opacity: 0 });
     
      // Create a timeline for fade in and fade out animations
      const tl = gsap.timeline({
        scrollTrigger: {
          trigger: scrollComponent,
          start: "top bottom",
          end: "bottom top",
          scrub: true,
        },
      });
     
      // Fade in animation
      tl.to(
        scrollComponent,
        { opacity: 1, duration: 0.5, ease: "none" },
        `+=${fadeInViewportOffset}`
      );
     
      // Fade out animation
      tl.to(
        scrollComponent,
        { opacity: 0, duration: 0.5, ease: "none" },
        `+=${fadeOutViewportOffset}`
      );
    });
     
    (async function animateSVG() {
        const response = await fetch(
            'https://uploads-ssl.webflow.com/641aa8ecc04bba58c591560d/641d5fe1c09aba5648ed5232_home-wavelength.svg'
        );
        const svgContent = await response.text();
     
        const svgEmbed = document.getElementById('svg-embed');
        svgEmbed.innerHTML = svgContent;
     
        await new Promise((resolve) => {
            svgEmbed.querySelector('svg').addEventListener('load', () => {
                resolve();
            });
        });
     
        const NUM_PATHS = 40;
        const ANIMATED_PATHS_RANGE = [3, 7]; // range of paths to animate with scroll
        const speedFactor = 1;
        const svgSpeed = 0.64;
        const animationDuration = 1.65; // in seconds
     
        let lastScrollTop =
            window.pageYOffset || document.documentElement.scrollTop - 70;
        let paths = [];
     
        function setDashProperties(path) {
            const pathLength = path.getTotalLength();
            path.style.strokeDasharray = pathLength;
            path.style.strokeDashoffset = 0;
        }
     
        function initializePaths() {
            for (let i = 0; i < NUM_PATHS; i++) {
                const path = document.getElementById(`path${i}`);
                setDashProperties(path);
                paths.push(path);
            }
        }
     
        function animatePaths() {
            const paths = document.querySelectorAll('.hero-svg-path');
     
            paths.forEach((path, index) => {
                const pathLength = path.getTotalLength();
                path.style.strokeDashoffset = pathLength;
                gsap.to(path, {
                    strokeDashoffset: 0,
                    duration: animationDuration,
                    ease: 'power1.inOut',
                    onStart: () => {
                        path.style.strokeOpacity = 1; // set the stroke opacity to 1 when the animation starts
                    },
                });
            });
        }
     
        function handleScroll() {
            const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
            const scrollHeight = document.body.scrollHeight - window.innerHeight;
            const scrollProgress = 1 - scrollTop / scrollHeight;
     
            const svg = document.getElementById('svg2');
            const horizontalMove = 0;
            const verticalMove = 0;
            const rotationSpeed = 0;
            const rotation = 0;
     
            gsap.to(svg, {
                x: horizontalMove,
                y: verticalMove,
                rotation: rotation,
                duration: 0.5,
            });
     
            const [animatedPathsStart, animatedPathsEnd] = ANIMATED_PATHS_RANGE;
            const animatedPaths = paths.slice(animatedPathsStart, animatedPathsEnd);
     
            animatedPaths.forEach((path) => {
                const pathLength = path.getTotalLength();
                const drawLength = pathLength * speedFactor * scrollProgress;
                const dashOffset = pathLength - drawLength;
                gsap.to(path, { strokeDashoffset: dashOffset, duration: 0.5 });
            });
     
            // Check if footer is in viewport
            const footer = document.querySelector('.footer');
            const footerRect = footer.getBoundingClientRect();
            const footerTopInView =
                footerRect.top >= 0 && footerRect.top < window.innerHeight;
            const footerBottomInView =
                footerRect.bottom > 0 && footerRect.bottom <= window.innerHeight;
     
            const heroSvgPaths = document.querySelectorAll('.hero-svg-path');
     
            if (footerTopInView || footerBottomInView) {
                // Footer is in viewport
                if (scrollTop > lastScrollTop) {
                    // User is scrolling down
                    heroSvgPaths.forEach((path) => {
                        gsap.to(path, { strokeOpacity: 0, duration: 0.5 });
                    });
                }
            } else {
                // Footer is not in viewport
                if (scrollTop < lastScrollTop) {
                    // User is scrolling up
                    heroSvgPaths.forEach((path) => {
                        gsap.to(path, { strokeOpacity: 1, duration: 1.8 });
                    });
                }
            }
     
            lastScrollTop = scrollTop;
        }
     
        function handleFooterIntersection(entries, observer) {
            entries.forEach((entry) => {
                if (entry.isIntersecting) {
                    // Footer is in view
                    const heroSvgPaths = document.querySelectorAll('.hero-svg-path');
                    heroSvgPaths.forEach((path) => {
                        gsap.to(path, { strokeOpacity: 0, duration: 0.5 });
                    });
                } else {
                    // Footer is out of view
                    const heroSvgPaths = document.querySelectorAll('.hero-svg-path');
                    heroSvgPaths.forEach((path) => {
                        gsap.to(path, { strokeOpacity: 1, duration: 1.8 });
                    });
                }
            });
        }
     
        function initializeAnimation() {
            initializePaths();
            animatePaths();
     
            // Set up the Intersection Observer to monitor the footer
            const observer = new IntersectionObserver(handleFooterIntersection);
            const footer = document.querySelector('.footer');
            observer.observe(footer);
     
            // Add a scroll listener to handle the SVG path animations on scroll
            window.addEventListener('scroll', handleScroll);
        }
     
        document.addEventListener('DOMContentLoaded', initializeAnimation);
        window.addEventListener('load', initializeAnimation);
    })();
     
    function initializeAnimation() {
      (async function animateFooterSVG() {
        const response = await fetch(
          'https://uploads-ssl.webflow.com/641aa8ecc04bba58c591560d/641e919471c8e50f896a65a6_footer-wavelength.svg'
        );
        const svgContent = await response.text();
     
        const svgEmbed = document.getElementById('footer-svg-embed');
        svgEmbed.innerHTML = svgContent;
     
        const NUM_PATHS = 37;
        const animationDuration = 2.0; // in seconds
        const drawInDuration = 2.0; // in seconds, controls the speed of the animation
        let paths = [];
     
        function setDashProperties(path) {
          const pathLength = path.getTotalLength();
          path.style.strokeDasharray = pathLength;
          path.style.strokeDashoffset = pathLength;
          path.style.strokeOpacity = 0;
        }
     
        function initializePaths() {
          const footerSvgPaths = document.querySelectorAll('.footer-svg-path');
          for (let i = 0; i < footerSvgPaths.length; i++) {
            const path = footerSvgPaths[i];
            setDashProperties(path);
            paths.push(path);
          }
        }
     
        function handleFooterIntersection(entries, observer) {
          entries.forEach((entry) => {
            if (entry.isIntersecting) {
              // Footer is in viewport
              paths.forEach((path) => {
                const pathLength = path.getTotalLength();
                gsap.to(path, {
                  strokeDashoffset: 0,
                  duration: drawInDuration,
                  ease: 'power1.inOut',
                  onStart: () => {
                    path.style.strokeOpacity = 1;
                  },
                });
              });
            } else {
              // Footer is not in viewport
              paths.forEach((path) => {
                const pathLength = path.getTotalLength();
                gsap.to(path, {
                  strokeDashoffset: pathLength,
                  duration: 0.5,
                  onComplete: () => {
                    path.style.strokeOpacity = 0;
                  },
                });
              });
            }
          });
        }
     
        initializePaths();
     
        const observer = new IntersectionObserver(handleFooterIntersection);
        const footer = document.querySelector('.footer');
        observer.observe(footer);
      })();
    }
     
    document.addEventListener('DOMContentLoaded', initializeAnimation);
    window.addEventListener('load', initializeAnimation);
     
    </script>
  3. 2 hours ago, GreenSock said:

    each section just a container with its own scrollbar

    I'm wondering what kind of logic I'd need to use in order to turn a section into a vertical scroll after clicking a button. Wouldn't I need to unpin the horizontal swipe section? I'm just not sure what to use in order to go from horizontal to vertical. I'm ok with having scrollbars on each axis.

  4. Thanks for the response! I'm actually looking for the .swipe-section to "un-pin" once it gets to the orange section in order for the actual .panel > .orange to be scrolled vertically instead of having a separate section that is not nested in the .swipe-section.

     

    I think the pseudo logic would be: Orange panel OnEnter { if( scrolledDown){unpin the .swipe-section}  }

    and then scrolling back to the top of the orange section would have logic to pin the .swipe-section again so that the panels can go back to the horizontal swipe animations.

     

     

  5. The first panel in this code pen (last code pen at the bottom) is 200vw, I'd like this panel to horizontally scroll to the end of the panel, and then trigger 'Observer.create({ slide from the left animation})' instead of having the Observer trigger right away on mousewheel.

     

    Would a timeline be best for this solution? Or how can I trigger a custom function at the bottom of the .panel viewport?

     

     

    I''m essentially combining:

    Horizontal Scroll

    See the Pen WNjaxKp by GreenSock (@GreenSock) on CodePen

     

    with Observer yPercent Animation

    See the Pen XWzRraJ by GreenSock (@GreenSock) on CodePen

     

    Thanks for your help!

     

    200vw panel I'd like to horizontally scroll until the end before the slide over animation occurs

    See the Pen MWVxzmr by ac09 (@ac09) on CodePen

  6. I'd like to copy this site's hero, the video expands but I'd also like it to scale down in size right after.

    https://www.basedesign.com/

     

    I've got the GSAP code working for the scaling up, but how do you add the scale down scroll trigger after the first one is complete?

    $(".sticky-circle_wrap").each(function (index) {
      let triggerElement = $(this);
      let targetElement = $(".sticky-circle_element");
    
      let tl = gsap.timeline({
        scrollTrigger: {
          trigger: triggerElement,
          // trigger element - viewport
          start: "top top",
          end: "bottom bottom",
          scrub: 1
        }
      });
      tl.fromTo(
        targetElement,
        {
                scale: 0.35,
          opacity: 0.40,
        },
        {
                scale: 0.75,
          opacity: 1,
          duration: 1
        }
      );
    
    });

     

  7. I've got 3 sections of copy separated by two bullet points. I'd like the first section to slide up on page load, then I'd like the second section (in between both bullets) to appear when all 5 of its sentences are in the viewport. Only problem is that its first and last line (lines with bullet points) are sharing lines with the first and last section. Is it possible to slide up only the copy which is within these bullet points, instead of the entire line sliding up which is what is happening now.

     

    Just to clarify when the line "aute irure dolor. ⬤ sequi nesciunt. Neque porro quisquam" scrolls into viewport I'd everything in green to slide up but not the part in red.

    Lorem ipsum dolor sit amet, consectetur adipiscing - the blue text slides into place on page load

    incididunt ut labore et dolore magna aliqua. Ut enim

    ad minim veniam, quis nostrud exercitation

    magni dolores eos qui. ⬤ Quis autem vel eum iure 

    Neque porro quisquam est, qui dolorem ipsum quia dolor

    reprehenderit qui in ea voluptate velit esse quam nihil

    ullamco laboris nisi ut aliquip ex ea commodo consequat 

    aute irure dolor. ⬤ sequi nesciunt. Neque porro quisquam - the green text slides into place when this line scrolls into viewport

    et quasi architecto beatae vitae dicta sunt explicabo

    accusantium doloremque laudantium, totam rem aperiam

    Feedback is appreciated                                                                    - the red text slides into place when this line scrolls into viewport

     

    See the Pen XWzvBZX by ac09 (@ac09) on CodePen

×
×
  • Create New...