Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ion-router-outlet custom transition not working for browser buttons #17722

Closed
berchik opened this issue Mar 7, 2019 · 7 comments
Closed

ion-router-outlet custom transition not working for browser buttons #17722

berchik opened this issue Mar 7, 2019 · 7 comments
Labels

Comments

@berchik
Copy link

berchik commented Mar 7, 2019

Current behavior:
I'm using the setting for the custom ion-router-outlet animation and it is working well when using page transition in PWA.

However, when using the browser back/forward buttons the animation is skipped.

(Seems like the angular router's "imperative" trigger property of the NavigationStart is inherited but "popstate" is not)

Expected behavior:
Animation should work in all page transitions

Related code:

IonicModule.forRoot({
      animated: true,
      navAnimation: myTransitionAnimation
    }),
onic:

   ionic (Ionic CLI)             : 4.10.3 (C:\Users\jo\AppData\Roaming\npm\node_modules\ionic)
   Ionic Framework               : @ionic/angular 4.0.2
   @angular-devkit/build-angular : 0.12.4
   @angular-devkit/schematics    : 7.2.4
   @angular/cli                  : 7.2.4
   @ionic/angular-toolkit        : 1.4.0

System:

   NodeJS : v10.15.1 (A:\Program Files\nodejs\node.exe)
   npm    : 6.5.0
   OS     : Windows 10



@ionitron-bot ionitron-bot bot added the triage label Mar 7, 2019
@liamdebeasi
Copy link
Contributor

Hi there,

Thanks for opening an issue with us! Would you be able to provide a repository with the code required to reproduce this issue?

Thanks!

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Mar 12, 2019
@ionitron-bot ionitron-bot bot removed the triage label Mar 12, 2019
@berchik
Copy link
Author

berchik commented Mar 18, 2019

Thank you for the reply.

This is true for any app, it is not a special case. Just serve the Ionic Conference App and try.

For example, click between Login/Support items in the menu and you'll see the page animation, but go back/forward with the browser and there is none.

On my project I replaced the animation builder:

@NgModule({
  …
  imports: [
    …
    IonicModule.forRoot({
      animated: true,
      navAnimation: myTransitionAnimation
    }),
    …
  ],

Which replaces the animation correctly, but still have no animations when using the browser's buttons.

As I mentioned, this happens because there is a hook to the router's "imperative" trigger but not to the "popstate", which is the browser's buttons.

Thanks!

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Mar 18, 2019
@lilian131
Copy link

hi @berchik please can you share code for myTransitionAnimation please

@liamdebeasi
Copy link
Contributor

Hi @berchik,

It's hard to say what's going on without seeing your myTransitionAnimation code. Could you share that?

Thanks!

@liamdebeasi liamdebeasi added the needs: reply the issue needs a response from the user label Mar 20, 2019
@ionitron-bot ionitron-bot bot removed the triage label Mar 20, 2019
@berchik
Copy link
Author

berchik commented Mar 31, 2019

Why hard? as I've mentioned it is not the animation function, which works correctly, but the missing hooks of the router. But here it is for your enjoyment, hopefully you can add the hooks so we wont have to bypass the ionic router:

export function myTransitionAnimation (AnimationC: Animation, navEl: HTMLElement, opts: TransitionOptions): Promise<Animation> {

    const isRTL = (navEl.ownerDocument as any).dir === 'rtl';
    const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
    const OFF_LEFT = isRTL ? '33%' : '-33%';

    const enteringEl = opts.enteringEl;
    const leavingEl = opts.leavingEl;

    const rootTransition = new AnimationC();
  rootTransition
    .addElement(enteringEl)
    .duration(opts.duration || DURATION)
    .easing(opts.easing || EASING)
      .beforeRemoveClass('ion-page-invisible');

    if (leavingEl && navEl) {
      const navDecor = new AnimationC();
      navDecor
        .addElement(navEl);

      rootTransition.add(navDecor);
    }

    const backDirection = (opts.direction === 'back');
    // setting up enter view
    const contentEl = enteringEl.querySelector(':scope > ion-content');
    const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
    const enteringToolBarEle = enteringEl.querySelector(':scope > ion-header > ion-toolbar');
    const enteringContent = new AnimationC();

    if (!contentEl && !enteringToolBarEle && headerEls.length === 0) {
      enteringContent.addElement(enteringEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs'));
    } else {
      enteringContent.addElement(contentEl);
      enteringContent.addElement(headerEls);
    }

    rootTransition.add(enteringContent);

    if (backDirection) {
           .fromTo(OPACITY, OFF_OPACITY, 1, true);
    } else {      
        .fromTo(OPACITY, OFF_OPACITY, 1, true);

    }

    if (enteringToolBarEle) {
      const enteringToolBar = new AnimationC();
      enteringToolBar.addElement(enteringToolBarEle);
      rootTransition.add(enteringToolBar);

      const enteringTitle = new AnimationC();
      enteringTitle.addElement(enteringToolBarEle.querySelector('ion-title'));

      const enteringToolBarItems = new AnimationC();
      enteringToolBarItems.addElement(enteringToolBarEle.querySelectorAll('ion-buttons,[menuToggle]'));

      const enteringToolBarBg = new AnimationC();
      enteringToolBarBg.addElement(shadow(enteringToolBarEle).querySelector('.toolbar-background'));

      const enteringBackButton = new AnimationC();
      const backButtonEl = enteringToolBarEle.querySelector('ion-back-button');
      enteringBackButton.addElement(backButtonEl);

      enteringToolBar
        .add(enteringTitle)
        .add(enteringToolBarItems)
        .add(enteringToolBarBg)
        .add(enteringBackButton);

      enteringTitle.fromTo(OPACITY, 0.01, 1, true);
      enteringToolBarItems.fromTo(OPACITY, 0.01, 1, true);

      if (backDirection) {
        enteringTitle.fromTo(TRANSLATEX, OFF_LEFT, CENTER, true);

        // back direction, entering page has a back button
        enteringBackButton.fromTo(OPACITY, 0.01, 1, true);
      } else {
        // entering toolbar, forward direction
        enteringTitle.fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);

        enteringToolBarBg
          .beforeClearStyles([OPACITY])
          .fromTo(OPACITY, 0.01, 1, true);

        // forward direction, entering page has a back button
        enteringBackButton.fromTo(OPACITY, 0.01, 1, true);

        if (backButtonEl) {
          const enteringBackBtnText = new AnimationC();
          enteringBackBtnText
            .addElement(shadow(backButtonEl).querySelector('.button-text'))
            .fromTo(TRANSLATEX, (isRTL ? '-100px' : '100px'), '0px');

          enteringToolBar.add(enteringBackBtnText);
        }
      }
    }

    // setup leaving view
    if (leavingEl) {

      const leavingContent = new AnimationC();
      leavingContent.addElement(leavingEl.querySelector(':scope > ion-content'));
      leavingContent.addElement(leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *'));
      rootTransition.add(leavingContent);

      if (backDirection) {
.fromTo(OPACITY, 0.99, 0, true);

      } else {
        // leaving content, forward direction
        leavingContent
          .fromTo(OPACITY, 0.9, 0, true);          
      }

      const leavingToolBarEle = leavingEl.querySelector(':scope > ion-header > ion-toolbar');
      if (leavingToolBarEle) {
        const leavingToolBar = new AnimationC();
        leavingToolBar.addElement(leavingToolBarEle);

        const leavingTitle = new AnimationC();
        leavingTitle.addElement(leavingToolBarEle.querySelector('ion-title'));

        const leavingToolBarItems = new AnimationC();
        leavingToolBarItems.addElement(leavingToolBarEle.querySelectorAll('ion-buttons,[menuToggle]'));

        const leavingToolBarBg = new AnimationC();
        leavingToolBarBg.addElement(shadow(leavingToolBarEle).querySelector('.toolbar-background'));

        const leavingBackButton = new AnimationC();
        const backButtonEl = leavingToolBarEle.querySelector('ion-back-button');
        leavingBackButton.addElement(backButtonEl);

        leavingToolBar
          .add(leavingTitle)
          .add(leavingToolBarItems)
          .add(leavingBackButton)
          .add(leavingToolBarBg);

        rootTransition.add(leavingToolBar);

        // fade out leaving toolbar items
        leavingBackButton.fromTo(OPACITY, 0.99, 0);
        leavingTitle.fromTo(OPACITY, 0.99, 0);
        leavingToolBarItems.fromTo(OPACITY, 0.99, 0);

        if (backDirection) {
          // leaving toolbar, back direction
          leavingTitle.fromTo(TRANSLATEX, CENTER, (isRTL ? '-100%' : '100%'));

          // leaving toolbar, back direction, and there's no entering toolbar
          // should just slide out, no fading out
          leavingToolBarBg
            .beforeClearStyles([OPACITY])
            .fromTo(OPACITY, 1, 0.01);

          if (backButtonEl) {
            const leavingBackBtnText = new AnimationC();
            leavingBackBtnText.addElement(shadow(backButtonEl).querySelector('.button-text'));
            leavingBackBtnText.fromTo(TRANSLATEX, CENTER, (isRTL ? -124 : 124) + 'px');
            leavingToolBar.add(leavingBackBtnText);
          }

        } else {
          // leaving toolbar, forward direction
          leavingTitle
            .fromTo(TRANSLATEX, CENTER, OFF_LEFT)
            .afterClearStyles([TRANSFORM]);

          leavingBackButton.afterClearStyles([OPACITY]);
          leavingTitle.afterClearStyles([OPACITY]);
          leavingToolBarItems.afterClearStyles([OPACITY]);
        }
      }
    }
    // Return the rootTransition promise
    return Promise.resolve(rootTransition);
  }

@ionitron-bot ionitron-bot bot added triage and removed needs: reply the issue needs a response from the user labels Mar 31, 2019
@liamdebeasi
Copy link
Contributor

Hi there,

Thanks for the follow up. After some more investigation, I've determined that this is likely a duplicate of #16569. Note that the issue I referenced discusses Location.back(), but that just uses window.history under the hood (which is what the browser back/forward buttons use).

I am going to close this issue in favor of the other one. We can continue any discussion regarding this issue over there. Thanks for using Ionic!

@ionitron-bot
Copy link

ionitron-bot bot commented May 10, 2019

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

@ionitron-bot ionitron-bot bot locked and limited conversation to collaborators May 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants