imacrayon / alpine-ajax

An Alpine.js plugin for building server-powered frontends.
https://alpine-ajax.js.org
MIT License
558 stars 11 forks source link

Smooth transition #83

Open pfisterjonas opened 1 month ago

pfisterjonas commented 1 month ago

Hey Crayon!

Great project you got. I am using it currently for an SPA like navigation in my Django App.

It all works really well (except for back/forth button for which I am still messing around with popstate and programmatic ajax calls - can't have it all I guess ;) unless I missed a solution here too?).

Anyway, I was wondering what your approach would be to make smooth slide out and slide in transitions. I am currently using the ajax:before Event to slide out the content. When the content is loaded, the transition is automatically applied to slide in. Most of the time, the content is loaded before the transition finishes, sometimes the load takes longer and i'll have an empty page for a while. Do you have any suggestions? Can i somehow have more fine control?

Thanks, keep it up!

imacrayon commented 1 month ago

Hi Pj,

My first thought would be to use the View Transitions, that would be the most performant and easy to use, the only drawback is that it's not fully cross-browser (yet).

You could make a page transitions with some CSS like this:

@keyframes fade-in {
  from { opacity: 0; }
}

@keyframes fade-out {
  to { opacity: 0; }
}

@keyframes slide-from-right {
  from { transform: translateX(25%); }
}

@keyframes slide-to-left {
  to { transform: translateX(25%); }
}

/* define animations for the old and new content */
::view-transition-old(slide-fade) {
  animation: 200ms ease 150ms both fade-out, 200ms ease 150ms both slide-to-left;
}
::view-transition-new(slide-fade) {
  animation: 300ms ease 50ms both fade-in, 300ms ease 50ms both slide-from-right;
}

#page {
  view-transition-name: slide-fade;
}

and then add the transition modifier to x-merge:

<div id="page" x-merge.transition>

If that won't cut it, I'd probably fallback to using events like you're doing. I'd use ajax:before to animate the page away and then ajax:after to animate it back into view.

If that feels like too much custom code though, there's also https://swup.js.org it does page transitions really well.