WIP Animations all over site
- Run a transition In for each page - Involve a "loader" panel on page change - TODO: tweak the animations and finish the concept
This commit is contained in:
63
src/utils/Transition.svelte
Normal file
63
src/utils/Transition.svelte
Normal file
@@ -0,0 +1,63 @@
|
||||
<script>
|
||||
import { stores } from '@sapper/app'
|
||||
import { pageReady, animDurationLong, pageTransition } from './store'
|
||||
const { page } = stores()
|
||||
|
||||
// Components
|
||||
import TitleSite from '../atoms/TitleSite'
|
||||
import IconGlobe from '../atoms/IconGlobe'
|
||||
|
||||
// Animations
|
||||
import { animateIn, animateOut } from '../animations/Transition'
|
||||
|
||||
|
||||
/*
|
||||
** PAGE LOADING PROCESS
|
||||
** 1. Set pageReady to false
|
||||
** 1. Runs the Loader transition In
|
||||
** ?. The next page changes the value of pageReady when mounted (or later)
|
||||
** 2. The Loader detects the value change of pageReady
|
||||
** 3. Hide the loader with transition Out
|
||||
** 4. The Loader runs the page transition In via pageTransition
|
||||
*/
|
||||
let firstLoad = true
|
||||
|
||||
// 1. Watch page change
|
||||
page.subscribe(() => {
|
||||
// Run the loader animation (only after first load)
|
||||
if (!firstLoad && process.browser) {
|
||||
animateIn()
|
||||
}
|
||||
// Set pageReady to false (?)
|
||||
pageReady.set(false)
|
||||
})
|
||||
|
||||
// 2. Watch when loaded changes
|
||||
pageReady.subscribe(loaded => {
|
||||
if (loaded) {
|
||||
setTimeout(() => {
|
||||
// Scroll back to top of page
|
||||
window.scrollTo(0,0)
|
||||
// 3. Hide the loader
|
||||
// Also sets firstLoad to false in order to show the second icon afterwards
|
||||
animateOut(() => firstLoad = false)
|
||||
}, 200) // This duration allows to not come over the transition In
|
||||
// [OU ALORS] les pages changent la valeur de loaded plus tard
|
||||
|
||||
// 4. Run the page's transition in, but a little bit before the end of the loader
|
||||
setTimeout(() => {
|
||||
pageTransition.onAnimationEnd()
|
||||
}, animDurationLong * 0.666 + 200)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="transition" id="transition" aria-hidden="true">
|
||||
<div class="loader">
|
||||
{#if firstLoad}
|
||||
<TitleSite />
|
||||
{:else}
|
||||
<IconGlobe width="44" color="#fff" animated="true" />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,23 +0,0 @@
|
||||
// import anime from 'animejs'
|
||||
import { crossfade } from 'svelte/transition'
|
||||
import { quartOut } from 'svelte/easing'
|
||||
|
||||
|
||||
// Crossfade transition
|
||||
export const [crossfadeSend, crossfadeReceive] = crossfade({
|
||||
duration: d => Math.sqrt(d * 200),
|
||||
|
||||
fallback(node, params) {
|
||||
const style = getComputedStyle(node)
|
||||
const transform = style.transform === 'none' ? '' : style.transform
|
||||
|
||||
return {
|
||||
duration: 600,
|
||||
easing: quartOut,
|
||||
css: t => `
|
||||
transform: ${transform} scale(${t});
|
||||
opacity: ${t}
|
||||
`
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -25,4 +25,15 @@ export let currentLocation = writable()
|
||||
export let currentPhotos = writable()
|
||||
|
||||
// State
|
||||
export let loaded = writable(false)
|
||||
// export let ready = writable(false)
|
||||
export let pageReady = writable(false)
|
||||
export const pageTransition = {
|
||||
onAnimationEnd () {}
|
||||
}
|
||||
|
||||
|
||||
/* ==========================================================================
|
||||
Animation related
|
||||
========================================================================== */
|
||||
export const animDuration = 1400
|
||||
export const animDurationLong = 1800
|
||||
|
||||
Reference in New Issue
Block a user