Jump to content
Search Community

Cyd

Business
  • Posts

    4
  • Joined

  • Last visited

Posts posted by Cyd

  1. Hi Zach, thanks, it took some time but I managed to recreate my issue in code sandbox https://codesandbox.io/s/rough-moon-171sw?file=/layouts/default.vue

    The problem arises when you switch pages (route) with a nuxt link, it keeps it's initial data and I do not know how to remove all the scrolltrigger and locomotive scroll data beforeDestroy. 
    I've tried killing all scrolltrigger instances in the Nuxt beforeDestroy method withScrollTrigger.getAll().forEach((trigger) => trigger.kill());

    And stopping locoscroll with locoScroll.stop() but it's like it's all initiated multiple times or something.
     

  2. It appears as though the scrollerProxy is initiated multiple times after routing which causes the matrix 3d animation to jump from -232213 to 0 and back.
    I think this is because the nuxt instance is kept while routing between pages that also use the _.vue page template but I cant figure out how to force it to forget the past scrollerProxy 😢
    Any advice as to how to initiate smoothscrolling in Nuxt?
     

    // _.vue template
    <template>
        <div>
        </div>
    </template>
    
    <script>
    import { gsap } from 'gsap'
    import { ScrollTrigger } from 'gsap/ScrollTrigger'
    gsap.registerPlugin(ScrollTrigger)
    export default {
        mounted() {
            this.smooth()
            this.$forceUpdate()
        },
        destroyed() {
            // used to kill the ScrollTrigger instance for this component
            this.expand = false
        },
        methods: {
            smooth() {
                if (process.client) {
                    window.scrollTo(0,0)
                    const locoScroll = new this.LocomotiveScroll({
                        el: document.querySelector('.smooth-scroll'),
                        smooth: true
                    })
                    // each time Locomotive Scroll updates, tell ScrollTrigger to update too (sync positioning)
                    locoScroll.on('scroll', ScrollTrigger.update)
    
                    ScrollTrigger.scrollerProxy('.smooth-scroll', {
                        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('.smooth-scroll').style.transform ? 'transform' : 'fixed'
                    })
                    // 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()
                    const headerItems = ['.header__logo', '.nav', '.header__trigger']
                    if (!this.isTouchDevice()) {
                        headerItems.forEach((item) => {
                            gsap.to(item, {
                                scrollTrigger: {
                                    trigger: '.header',
                                    scroller: '.smooth-scroll',
                                    scrub: true,
                                    pin: true,
                                    start: 'top',
                                    end: document.querySelector('body').offsetHeight,
                                    pinSpacing: false,
                                },
                                y: document.querySelector('body').offsetHeight,
                                transformOrigin: 'center top',
                                ease: 'none'
                            })
                        })
                        const largeMedia = document.querySelectorAll('.large-media.no-controls')
                        if (largeMedia) {
                            largeMedia.forEach((media) => {
                                let mediaItem = media.querySelector('video')
                                if (media.querySelector('img')) {
                                    mediaItem = media.querySelector('img')
                                }
                                gsap.to(mediaItem, {
                                    scrollTrigger: {
                                        trigger: media,
                                        scroller: '.smooth-scroll',
                                        scrub: true,
                                        start: 'top',
                                        end: 'bottom',
                                    },
                                    y: '100%',
                                    transformOrigin: 'center top',
                                    ease: 'none'
                                })
                            })
                        }
    
                        const nextCase = document.querySelector('.next-case')
                        if (nextCase) {
                            gsap.to('.next-case .large-media', {
                                scale: 1,
                                opacity: 0,
                                scrollTrigger: {
                                    trigger: nextCase,
                                    scroller: '.smooth-scroll',
                                    start: `top-=${window.innerHeight / 2}`,
                                    end: `bottom-=${window.innerHeight}`,
                                    scrub: 1,
                                }
                            })
                            gsap.to('.next-case__background', {
                                opacity: 1,
                                scrollTrigger: {
                                    trigger: nextCase,
                                    scroller: '.smooth-scroll',
                                    start: `top-=${window.innerHeight / 2}`,
                                    end: `bottom-=${window.innerHeight}`,
                                    scrub: 1,
                                }
                            })
                            gsap.to('.large-text-header', {
                                opacity: 1,
                                scrollTrigger: {
                                    trigger: nextCase,
                                    scroller: '.smooth-scroll',
                                    start: `top-=${window.innerHeight / 2}`,
                                    end: `bottom-=${window.innerHeight}`,
                                    scrub: 1,
                                }
                            })
                            const observerTrigger = document.querySelector('.next-case__observer-trigger')
                            const onIntersection = (entries) => {
                                for (const entry of entries) {
                                    if (entry.isIntersecting) {
                                        this.loaded = entry.intersectionRatio
                                        if (entry.intersectionRatio > 0.95) {
                                            this.background = true
                                            if (!this.expand) {
                                                // window.location.href = nextCase.querySelector('a').getAttribute('href') // goor, doch effectief
                                                this.$router.push(nextCase.querySelector('a').getAttribute('href'))
                                                this.expand = true
                                            }
                                        }
                                    }
                                }
                            }
                            let threshold = [] // create array with numbers between 0 and 1
                            for (var i = 0; i <= 100; i++) {
                                threshold.push(i / 100)
                            }
                            const observer = new IntersectionObserver(onIntersection, { threshold })
                            observer.observe(observerTrigger)
                        }
                    }
                }
            },
            isTouchDevice() {
                try {
                    document.createEvent('TouchEvent')
                    return true
                } catch (e) {
                    return false
                }
            }
        },
    }
    </script>


     

×
×
  • Create New...