✨ Finish to replace Anime with Motion One for page animations
Page intro animation and reveal that has now been simplified as Motion One manages an inView option (that uses IntersectionObserver)
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { map } from '$utils/functions'
|
||||
import { reveal, fly } from '$animations/index'
|
||||
import reveal from '$animations/reveal'
|
||||
|
||||
export let tag: string
|
||||
export let label: string = undefined
|
||||
@@ -46,17 +46,15 @@
|
||||
|
||||
|
||||
const revealOptions = animate ? {
|
||||
animation: fly,
|
||||
children: '.char',
|
||||
animation: { y: ['-105%', 0] },
|
||||
options: {
|
||||
children: '.char',
|
||||
stagger: 60,
|
||||
duration: 1600,
|
||||
from: '-105%',
|
||||
opacity: false,
|
||||
delay: 200,
|
||||
stagger: 0.06,
|
||||
duration: 1.6,
|
||||
delay: 0.2,
|
||||
threshold: 0.2,
|
||||
},
|
||||
threshold: 0.2,
|
||||
} : {}
|
||||
} : null
|
||||
</script>
|
||||
|
||||
<svelte:window
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import SplitText from '$components/SplitText.svelte'
|
||||
import { reveal, fly } from '$animations/index'
|
||||
import reveal from '$animations/reveal'
|
||||
import { DURATION } from '$utils/contants'
|
||||
|
||||
export let variant: string = 'lines'
|
||||
@@ -14,16 +14,14 @@
|
||||
{#if tag === 'h1'}
|
||||
<h1 class="site-title site-title--{variant}"
|
||||
use:reveal={{
|
||||
animation: fly,
|
||||
children: '.char',
|
||||
animation: { y: ['105%', 0] },
|
||||
options: {
|
||||
children: '.char',
|
||||
stagger: 40,
|
||||
duration: 1000,
|
||||
from: '110%',
|
||||
opacity: false,
|
||||
delay: DURATION.PAGE_IN
|
||||
stagger: 0.04,
|
||||
duration: 1,
|
||||
delay: DURATION.PAGE_IN / 1000,
|
||||
threshold: 0,
|
||||
},
|
||||
threshold: 0,
|
||||
}}
|
||||
>
|
||||
<SplitText text="Houses" mode="chars" class="pink mask" />
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores'
|
||||
import { getContext } from 'svelte'
|
||||
import { fly, reveal } from '$animations/index'
|
||||
import reveal from '$animations/reveal'
|
||||
// Components
|
||||
import Icon from '$components/atoms/Icon.svelte'
|
||||
|
||||
@@ -42,14 +42,12 @@
|
||||
class:is-open={isOpen}
|
||||
class:is-over={isOver}
|
||||
use:reveal={{
|
||||
animation: fly,
|
||||
animation: { y: [24, 0], opacity: [0, 1] },
|
||||
options: {
|
||||
from: 24,
|
||||
to: 0,
|
||||
duration: 1000,
|
||||
easing: 'easeOutQuart',
|
||||
delay: 600,
|
||||
}
|
||||
duration: 1,
|
||||
delay: 0.6,
|
||||
threshold: 0,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<button class="switcher__button" title="{!isOpen ? 'Open' : 'Close'} menu" tabindex="0"
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { navigating } from '$app/stores'
|
||||
import { getContext, onMount } from 'svelte'
|
||||
import anime, { type AnimeTimelineInstance } from 'animejs'
|
||||
import { stagger, timeline } from 'motion'
|
||||
import { cartOpen } from '$utils/stores/shop'
|
||||
import { smoothScroll } from '$utils/functions'
|
||||
import { DELAY } from '$utils/contants'
|
||||
import { quartOut } from '$animations/easings'
|
||||
// Components
|
||||
import Image from '$components/atoms/Image.svelte'
|
||||
import ButtonCart from '$components/atoms/ButtonCart.svelte'
|
||||
@@ -37,46 +40,52 @@
|
||||
/**
|
||||
* Animations
|
||||
*/
|
||||
// Setup animations
|
||||
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||
duration: 1600,
|
||||
easing: 'easeOutQuart',
|
||||
autoplay: false,
|
||||
const animation = timeline([
|
||||
// Hero image
|
||||
['.shop-page__background', {
|
||||
scale: [1.06, 1],
|
||||
opacity: [0, 1],
|
||||
}, {
|
||||
at: 0.4,
|
||||
duration: 2.4,
|
||||
}],
|
||||
|
||||
// Intro top elements
|
||||
['.shop-page__intro .top > *', {
|
||||
y: [-100, 0],
|
||||
opacity: [0, 1],
|
||||
}, {
|
||||
at: 0.4,
|
||||
delay: stagger(0.25),
|
||||
}],
|
||||
|
||||
// Hero title
|
||||
['.shop-page__title h1', {
|
||||
y: [32, 0],
|
||||
opacity: [0, 1],
|
||||
}, {
|
||||
at: 0.5,
|
||||
}],
|
||||
|
||||
// Intro navbar
|
||||
['.shop-page__nav .container > *, .shop-page__intro .button-cart', {
|
||||
y: [100, 0],
|
||||
opacity: [0, 1],
|
||||
}, {
|
||||
at: 0.7,
|
||||
delay: stagger(0.25),
|
||||
}]
|
||||
], {
|
||||
delay: $navigating ? DELAY.PAGE_LOADING / 1000 : 0,
|
||||
defaultOptions: {
|
||||
duration: 1.6,
|
||||
easing: quartOut,
|
||||
},
|
||||
})
|
||||
animation.stop()
|
||||
|
||||
// Hero image
|
||||
timeline.add({
|
||||
targets: '.shop-page__background',
|
||||
scale: [1.06, 1],
|
||||
opacity: [0, 1],
|
||||
duration: 2400,
|
||||
}, 400)
|
||||
|
||||
// Hero title
|
||||
timeline.add({
|
||||
targets: '.shop-page__title h1',
|
||||
translateY: [32, 0],
|
||||
opacity: [0, 1],
|
||||
}, 500)
|
||||
|
||||
// Intro top elements
|
||||
timeline.add({
|
||||
targets: '.shop-page__intro .top > *',
|
||||
translateY: [-100, 0],
|
||||
delay: anime.stagger(250),
|
||||
}, 400)
|
||||
|
||||
// Intro navbar
|
||||
timeline.add({
|
||||
targets: '.shop-page__nav .container > *, .shop-page__intro .button-cart',
|
||||
opacity: [0, 1],
|
||||
translateY: [100, 0],
|
||||
translateZ: 0,
|
||||
delay: anime.stagger(250),
|
||||
}, 700)
|
||||
|
||||
// Transition in
|
||||
requestAnimationFrame(timeline.play)
|
||||
// Run animation
|
||||
requestAnimationFrame(animation.play)
|
||||
|
||||
|
||||
// Destroy
|
||||
|
||||
Reference in New Issue
Block a user