Jump to content
Search Community

Flip Plugin: Element Jumps from Lower Position During Transition

Clement P

Go to solution Solved by Clement P,

Recommended Posts

Clement P
Posted

Hey GSAP Community,

 

I'm currently working on a page transition using GSAP's flip plugin, and I'm encountering an issue where the element seems to "jump" from a lower position during the transition, which affects the UX.

 

I'm using Barba.js for page transitions, and GSAP/Flip are used to animate the transition.

The element in question is cloned and moved to a new container during the transition.

 

I've attached a video that better explains my problem, and here's my JavaScript code that handles the transition. If you need more elements (HTML content, styles), don't hesitate to let me know!

 

gsap.registerPlugin(ScrollTrigger, CustomEase, Flip);

const $ = (el) => document.querySelector(el)

let scroll;
const BASIC_DURATION = 1.2;
let transitionOffset = 1100;
let staggerDefault = 0.07;

CustomEase.create("primary-ease", "0.42, 0.1, 0.05, 0.89");
CustomEase.create("primary-ease-out", ".34, 1.56, 0.64, 1");

function leaveWorkSingle(container) {
    const tl = gsap.timeline({
        default: {
            duration: BASIC_DURATION,
            ease: "primary-ease"
        }
    })

    let transitionElements = document.querySelector('.transition-work-single');
    let transitionElementsFooterImage = transitionElements.querySelector('.img-next');

    let cloneTransitionElements = transitionElements.cloneNode(true);
    let transitionElementsNewContainer = document.querySelector('.transition-work-single-container');
    let transitionElementsOldContainer = document.querySelector('.transition-work-single-old-container');

    let transitionElementsState = Flip.getState(".transition-work-single");

    transitionElementsNewContainer.classList.add('transitioning');

    transitionElementsNewContainer.appendChild(transitionElements);
    transitionElementsOldContainer.appendChild(cloneTransitionElements);

    tl.set('main.main', {
        autoAlpha: 0
    })

    tl.add(Flip.from(transitionElementsState, {
        ease: "primary-ease",
        duration: 1.2,
        absolute: true,
    }), 0.5);

    tl.set(cloneTransitionElements, {
        autoAlpha: 0
    });
}

function enterWorkSingle(container) {
    // todo
    const tl = gsap.timeline({
        default: {
            duration: BASIC_DURATION,
            ease: "primary-ease"
        }
    })

    tl.set('main.main', {
        autoAlpha: 1,
        onComplete: () => {
            console.log('done')
            let r = $('.transition-work-single-container.transitioning .transition-work-single')
            console.log(r)
            r.remove()
        }
    })
}

function delay(n) {
    n = n || 2000;
    return new Promise((done) => {
        setTimeout(() => {
            done();
        }, n);
    });
}

function initLenis() {
    scroll = new Lenis({
       duration: 1
    })

    scroll.on('scroll', ScrollTrigger.update)
 
    gsap.ticker.add((time) => {
       scroll.raf(time * 1000);
    })

    gsap.ticker.lagSmoothing(0)
}

function initTransitions() {
    history.scrollRestoration = "manual";

    barba.hooks.afterEnter(() => {
        window.scrollTo(0, 0);
        ScrollTrigger.refresh();
    });

    barba.init({
        sync: true,
        debug: false,
        timeout: 7000,
        transitions: [
            {
                name: 'from-to-work-single',
                from: {
                    namespace: ['work-single']
                },
                to: {
                    namespace: ['work-single']
                },
                async leave(data) {
                    leaveWorkSingle(data.current.container);
                    await delay(1700);
                },
                async enter(data) {
                    enterWorkSingle(data.next.container);
                },
                async beforeEnter(data) {
                    // ScrollTrigger.getAll().forEach(t => t.kill());
                    initSmoothScroll(data.next.container);
                    // initScript();
                },
            }
        ]
    });

    function initSmoothScroll(container) {
        initLenis();
        ScrollTrigger.refresh();
    }
}

initTransitions();

 

Thank you in advance for your help.

GSAP Helper
Posted

Without a minimal demo, it's very difficult to troubleshoot; the issue could be caused by CSS, markup, a third party library, a 3rd party script, etc. Would you please provide a very simple CodePen or Stackblitz that illustrates the issue? 

 

Please don't include your whole project. Just some colored <div> elements and the GSAP code is best. See if you can recreate the issue with as few dependencies as possible. Start minimal and then incrementally add code bit by bit until it breaks. Usually people solve their own issues during this process! If not, at least we have a reduced test case which greatly increases your chances of getting a relevant answer.

 

See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen.

that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo

 

Using a framework/library like React, Vue, Next, etc.? 

CodePen isn't always ideal for these tools, so here are some Stackblitz starter templates that you can fork and import the gsap-trial NPM package for using any of the bonus plugins: 

 

Please share the StackBlitz link directly to the file in question (where you've put the GSAP code) so we don't need to hunt through all the files. 

 

Once we see an isolated demo, we'll do our best to jump in and help with your GSAP-specific questions. 

Clement P
Posted

Thanks a lot for your reply!

It's weird, because on the following demo it looks like it's working, but on my laptop it's not. Maybe it's a dimensional problem.

Also, you may notice that there's a lag between the next section and the intro section. I'd like to animate it, but I don't know if it's possible with the Flip plugin.

 

https://stackblitz.com/edit/stackblitz-starters-tuxqmn7i?file=package.json

 

N.B I've just tested with another browser, Chrome, and the result is perfect except for the “gap” between the title and the image, which is not animated. On the Arc browser, it doesn't give the same result and I can't figure out why.

Posted

Hi,

 

I don't have time right now to check your demo in depth and see what could be the problem. If you're animating more than one element, all those elements should/could be on the getState() method and/or use the targets config option:

https://gsap.com/docs/v3/Plugins/Flip/static.from()#special-properties

 

Hopefully in the coming days I'll be able to get a better look at your demo.

  • Solution
Clement P
Posted

Well, I just solved the problem by adding an animation on the margin-top value of my element.

However, I don't know if I'm doing right but now, in all browser it works (I've updated the StackBlitz demo).

Maybe, on the Arc browser, I met a cache problem?

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...