Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aurelia router view animation with swap-order="with"

Tags:

aurelia

I am using aurelia-animator-css to animate router views. Upon navigation to a new router view, I want the current view to slide off screen to the left while the new view slides onto the screen from the right.

Here is my router-view element:

<router-view swap-order="with"></router-view>

Here is the top element in each of the views:

<div class="pages au-animate">

And here is the css:

@keyframes slideLeftIn {
  0% {
    transform: translate(100%, 0);
  }
  100% {
    transform: translate(0, 0);
  }
}
@keyframes slideLeftOut {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(-100%, 0);
  }
}
.pages.au-enter {
  transform: translate(100%, 0);
}
.pages.au-enter-active {
  animation: slideLeftIn 0.6s;
}
.pages.au-leave-active {
  animation: slideLeftOut 0.6s;
}

I am using autoprefixer, so there is no need for prefixes such as "webkit-".

With swap-order="with", the current view slides off screen to the left, and then the new view appears without sliding.

The same thing happens with swap-order="before".

Here's a youtube screen video with swap-order="with".

With swap-order="after", the current view slides off screen to the left, and then the new view slides in from the right.

Here's a youtube screen video with swap-order="after".

I would think that swap-order="with" would be the one that is needed in this situation. But swap-order="after" is closest to what I need, since both views actually perform slides, just not together.

like image 881
Jeff G Avatar asked Nov 08 '22 10:11

Jeff G


1 Answers

Note: This is not an answer to the question, but more an addition to the animation style and question from @powerbouy in the accepted answer.

If anyone came here, as I did, looking for a way to have a phone style navigation:

You would need two more animations, which inverts the direction.

@keyframes slideRightIn {
  0% {
    transform: translate(-100%, 0);
  }
  100% {
    transform: translate(0, 0);
  }
}
@keyframes slideRightOut {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(100%, 0);
  }
}

Then you would need a new set of animation classes:

.slide-right .pages.au-enter {
  transform: translate(-100%, 0);
}
.slide-right .pages.au-enter-active {
  animation: slideRightIn 0.4s;
}
.slide-right .pages.au-leave-active {
  animation: slideRightOut 0.4s;
}

To use the left to right backwards navigation style, you would need to apply the slide-right class to your an parent element of .pages

You could attach it on the router-view element in a back() method like:

  back() {
        document.querySelector('router-view').classList.add('slide-right');
        window.history.back(-1);
  }

Then on the detach() event, you remove it.

detached() {
    // remove class after animation. Only opt-in for showing "back" style animation.
    document.querySelector('router-view').classList.remove('slide-right');
}

UPDATE:

To also detect use of the browsers back button, you could tap into the popstate event. The PLATFORM object comes from the Aurelia PAL package.

Add an eventhandler:

backEventHandler = () => { this.back(true); };

Add event listener when component is attached:

attached() {
        PLATFORM.global.addEventListener("popstate", this.backEventHandler);
    }

Remove event listener when component is detached:

detached() {
        // remove class after animation. Only opt-in for showing "back" style animation.
        document.querySelector('router-view').classList.remove('slide-right');

        PLATFORM.global.removeEventListener("popstate", this.backEventHandler);
    }

Update the back() function to also include a parameter to tell if it's called from the browser or not.

back(native?: boolean) {
        document.querySelector('router-view').classList.add('slide-right');

        if (!native) {
            window.history.back(-1);
        }
    }
like image 97
scheien Avatar answered Dec 21 '22 15:12

scheien