Add photo Viewer entering animation
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/env'
|
import { browser } from '$app/env'
|
||||||
import { page } from '$app/stores'
|
import { page } from '$app/stores'
|
||||||
import { tick } from 'svelte'
|
import { goto } from '$app/navigation'
|
||||||
|
import { onMount, tick } from 'svelte'
|
||||||
import { scale } from 'svelte/transition'
|
import { scale } from 'svelte/transition'
|
||||||
import { quartOut } from 'svelte/easing'
|
import { quartOut } from 'svelte/easing'
|
||||||
import { getAssetUrlKey } from '$utils/helpers'
|
import { getAssetUrlKey } from '$utils/helpers'
|
||||||
@@ -10,8 +11,10 @@
|
|||||||
import { swipe } from '$utils/interactions/swipe'
|
import { swipe } from '$utils/interactions/swipe'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import advancedFormat from 'dayjs/plugin/advancedFormat.js'
|
import advancedFormat from 'dayjs/plugin/advancedFormat.js'
|
||||||
|
import anime from 'animejs'
|
||||||
// Components
|
// Components
|
||||||
import Metas from '$components/Metas.svelte'
|
import Metas from '$components/Metas.svelte'
|
||||||
|
import SplitText from '$components/SplitText.svelte'
|
||||||
import Image from '$components/atoms/Image.svelte'
|
import Image from '$components/atoms/Image.svelte'
|
||||||
import Icon from '$components/atoms/Icon.svelte'
|
import Icon from '$components/atoms/Icon.svelte'
|
||||||
import IconArrow from '$components/atoms/IconArrow.svelte'
|
import IconArrow from '$components/atoms/IconArrow.svelte'
|
||||||
@@ -208,6 +211,72 @@
|
|||||||
throw new Error('Error while loading new photos')
|
throw new Error('Error while loading new photos')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
// Setup animations
|
||||||
|
const timeline = anime.timeline({
|
||||||
|
duration: 1600,
|
||||||
|
easing: 'easeOutQuart',
|
||||||
|
})
|
||||||
|
|
||||||
|
anime.set('.viewer-photo__picture', {
|
||||||
|
opacity: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Photos
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer-photo__picture.is-1',
|
||||||
|
opacity: 1,
|
||||||
|
duration: 900,
|
||||||
|
}, 200)
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer-photo__picture:not(.is-0):not(.is-1)',
|
||||||
|
opacity: 1,
|
||||||
|
translateX (element: HTMLElement, index: number) {
|
||||||
|
const x = getComputedStyle(element).getPropertyValue('--offset-x').trim()
|
||||||
|
return [`-${x}`, 0]
|
||||||
|
},
|
||||||
|
delay: anime.stagger(55)
|
||||||
|
}, 400)
|
||||||
|
|
||||||
|
// Prev button
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer-photo__controls button:first-child',
|
||||||
|
translateX: [-16, 0],
|
||||||
|
opacity: [0, 1],
|
||||||
|
}, 600)
|
||||||
|
// Next button
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer-photo__controls button:last-child',
|
||||||
|
translateX: [16, 0],
|
||||||
|
opacity: [0, 1],
|
||||||
|
}, 600)
|
||||||
|
|
||||||
|
|
||||||
|
// Infos
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer-photo__info > *',
|
||||||
|
translateY: [24, 0],
|
||||||
|
opacity: [0, 1],
|
||||||
|
delay: anime.stagger(200)
|
||||||
|
}, 400)
|
||||||
|
|
||||||
|
|
||||||
|
anime.set('.viewer-photo__index', { opacity: 0 })
|
||||||
|
// Index
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer-photo__index',
|
||||||
|
opacity: 1,
|
||||||
|
duration: 900,
|
||||||
|
}, 600)
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer-photo__index .char',
|
||||||
|
translateY: ['100%', 0],
|
||||||
|
delay: anime.stagger(200),
|
||||||
|
duration: 1000,
|
||||||
|
}, 1100)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window
|
<svelte:window
|
||||||
@@ -267,9 +336,10 @@
|
|||||||
</ButtonCircle>
|
</ButtonCircle>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="viewer-photo__index title-index">
|
|
||||||
{(currentPhotoIndex < 10) ? '0' : ''}{currentPhotoIndex}
|
<div class="viewer-photo__index title-index">
|
||||||
</span>
|
<SplitText text="{(currentPhotoIndex < 10) ? '0' : ''}{currentPhotoIndex}" mode="chars" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="viewer-photo__info">
|
<div class="viewer-photo__info">
|
||||||
|
|||||||
@@ -300,6 +300,7 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
@include bp (md, max) {
|
@include bp (md, max) {
|
||||||
font-size: clamp(#{rem(80px)}, 24vw, #{rem(120px)});
|
font-size: clamp(#{rem(80px)}, 24vw, #{rem(120px)});
|
||||||
|
|||||||
Reference in New Issue
Block a user