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
Ionic Page transition - how to implement in router? #32
Comments
I'd love to help. Looked into the
async loadRoute() {
const { router } = this
const pipeline = [
this.runBeforeUrlChangeHooks,
this.loadComponents,
this.runGuards,
this.runPreloads,
]
async loadComponents() {
this.log.debug('load components', this) // ROUTIFY-DEV-ONLY
await Promise.all(this.fragments.map(fragment => fragment.node.loadModule()))
return true
}
// hook available from outsude
async runBeforeUrlChangeHooks() {
return await this.router.beforeUrlChange.run({ route: this })
} So it looks like the
export class RouteFragment {
/**
* @param {Route} route the route this fragment belongs to
* @param {RNodeRuntime} node the node that corresponds to the fragment
* @param {String} urlFragment a fragment of the url (fragments = url.split('/'))
* @param {Object<string, any>} params
*/
constructor(route, node, urlFragment, params) {
this.route = route
this.node = node
/** @type {Partial<RoutifyLoadReturn>} */
this.load = undefined
this.urlFragment = urlFragment
this.params = params
} The For route transitions Apparently you can create your own decorators with transitions In particular see the import { fade } from 'svelte/transition'
const configs = [
{
condition: (meta)=>true,
transition: fade,
/** inParams: {}, optional **/
/** outParams: {} optional **/
}
] To customize transitions, see:
I think to fully customize navigation transitions, you would need to create your own variant of BaseTransition where you create your own variant of <div
class="transition node{get(node).__file.id}"
in:transition|local={inParams}
out:transition|local={outParams}
>
<slot />
</div> So you are not limited by the built-in |
This might be a good starting point: https://css-tricks.com/native-like-animations-for-page-transitions-on-the-web/ .page-enter-active {
transition: opacity 0.25s ease-out;
}
.page-leave-active {
transition: opacity 0.25s ease-in;
}
.page-enter,
.page-leave-active {
opacity: 0;
} I would think that the trick is to create and expose some kind of shared state (route store) between pages, then have particular page components activate their transitions on state changed? Then hook up the |
<script>
import { writable } from "svelte/store";
export const routing = writable({});
</script>
<script>
import { routing } from "./stores.js";
import { beforeUrlChange, afterUrlChange } from "@roxi/routify"
$beforeUrlChange((event, route) => {
routing.set({state: 'before', event, route})
})
$afterPageLoad((page) => {
routing.update(data => ({...data, state: 'after', page}))
})
</script> Perhaps using https://www.routify.dev/docs/helpers#is-changing-page Then create some components that subscribe to the store and activate the transitions? |
Interesting article with some patterns here: https://imfeld.dev/writing/svelte_overlapping_transitions and https://blog.logrocket.com/essential-transitions-and-animations-in-svelte/ Looks like the key is to use https://svelte.dev/tutorial/key-blocks like in https://stackoverflow.com/questions/69186922/transition-when-cycling-through-store-in-svelte |
Note that in routify 3, they are called hooks, not helpers https://v3.ci.routify.dev/docs#guide/concepts/hooks Elements on individual pages can be accessed via context and nodes https://v3.ci.routify.dev/docs#guide/concepts/nodes |
I think the page transitions in this video could be an inspiration: https://www.youtube.com/watch?v=G3KFXKawy7Y&list=PLA9WiRZ-IS_zXZZyW4qfj0akvOAtk6MFS&index=18 Looks like a very neat design. |
Hi @kristianmandrup - thank you so much for this! I will study more carefully in the coming days/week - busy on something else (=J O B). But really appreciate the effort! Ps. I want to move away from routify in favor of sveltekit router in spa mode |
Placeholder - Geoff Rich on element transitions |
By chance, I just discovered the new PageTransition API available in Chrome canary (ie native support). https://www.youtube.com/watch?v=JCJUPJ_zDQ4 - Bringing page transitions to the web |
Oh, we discovered the same PageTransition API independently :) |
Aha, here is a Svelte demo not using the Page Transition API - https://github.com/pngwn/svelte-travel-transitions |
All the info for his presentation: https://geoffrich.net/posts/svelte-london-2022/ I would think that his code would just need to hooked up to a wrapper around roxify router which provides slightly more information and flexibility. |
For Routify v3 the /** @type {Route[]} */
history = [] Hooks type defs * @typedef { function({route: Route}): any } BeforeUrlChangeCallback
* @typedef { function({
* route: Route,
* history: Route[]
* }): any } AfterUrlChangeCallback
init(input) {
if (this.url.getActive()) {
this.log.debug('router was created with activeUrl') // ROUTIFY-DEV-ONLY
this._setUrl(this.url.getActive(), 'pushState', true)
}
}
/**
*
* @param {string} url
* @param {UrlState} mode pushState, replaceState or popState
* @param {boolean} [isInternal=false] if the URL is already internal, skip rewrite.toInternal
* @param {Object=} state a state to attach to the route
* @returns {Promise<true|false>}
*/
async _setUrl(url, mode, isInternal, state) {
const { activeRoute, pendingRoute } = this
// ...
const route = new Route(this, url, mode, state)
// ...
pendingRoute.set(route)
await route.loadRoute()
// ...
}
class Route {
constructor(router, url, mode, state = {}) {
this.router = router
this.url = url
this.mode = mode
this.state = state
// ...
}
async runBeforeUrlChangeHooks() {
return await this.router.beforeUrlChange.run({ route: this })
}
async loadRoute() {
const { router } = this
const pipeline = [
this.runBeforeUrlChangeHooks,
this.loadComponents,
this.runGuards,
this.runPreloads,
]
this.loaded = new Promise(async (resolve, reject) => {
// will run beforeUrlChange
for (const pretask of pipeline) {
// ...
})
// ...
const $activeRoute = this.router.activeRoute.get()
if ($activeRoute) router.history.push($activeRoute)
router.activeRoute.set(this)
router.afterUrlChange.run({
route: this,
history: [...router.history].reverse(),
})
})
return this.loaded
}
} |
According to Geoff's code we need the |
@Tommertom Routify author has just provided this store for integration with Page Transition wrapper by @geoffrich . $: store = {
from: $activeRoute
to: $pendingRoute
state: $pendingRoute ? 'started' : 'complete'
} |
I've just created this sample repo using latest Svelte, routify 3 and the Page Transition API wrapper by @geoffrich This could serve as a simple starting point to build on. |
Hey there So from the rapid reading I have done I see a few things
Example - if the outgoing page has a back button, that specific button itself, on top of the page animation, should animate in a bit different way - like defined in https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/transition/ios.transition.ts So, I am just curious if that part is included in your setup - and if so, does the node in Routify (let's stick to Routify for this) really refer to the mounted components? |
Hi @Tommertom, from my understanding and investigation, SvelteKit does not currently support Ionic apps. Hence I'm not sure if you can use the SvelteKit Router instead of Routify. The example app by @geoffrich as demonstrated in his video showcases the back button and an image on a page being animated independently of the page itself during the page transition. This fine-grained animation is supported in https://github.com/kristianmandrup/page-transition-app/blob/main/src/lib/page-transition.ts and https://github.com/kristianmandrup/page-transition-app/blob/main/src/lib/reduced-motion.ts in particular using (If I recall correctly) |
Sveltekit and Ionic (my lib that is) go well together as long as sveltekit runs SPA mode I have it running - I just need to go to their latest breaking release and then implement it |
Very cool :) SvelteKit sure moves fast... |
Closing this issue as I am moving the ionic package related stuff to the ionic-svelte npm package repo If you haven't seen this - please check out |
For page transitions Ionic has this really cool transition which is more than just a single page fly-in - what is happening now.
It looks into the various elements of the incoming component and gives them specific transitions. Like the header-title, the default back-button and the page itself. Also the outoging component gets this special treatment as a whole and for its elements.
For now I have been able to pin down this transition in their code. And here an example link to the transition in ios: https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/transition/ios.transition.ts
The function responsible for adding the transitions to the dom elements seems to be :
(taken from the vue implementation -and I need to check how it relates to the ios.transitions.ts)
The API requires the enteringElement and the leaving element, besides a directions. The showGoBack is related to the BackButton mostly shown top left or top right corner. animationBuilder is I believe a customer animation and the boolean I don't know, but probably not of big interest for now?
So, the question is how to hook this up in Routify. Maybe through the helpers you have? But I also think/fear/believe a more deeper connection might be needed.
Looking for help on how to achieve this.
The text was updated successfully, but these errors were encountered: