Run page animations onMount instead of browser
This commit is contained in:
@@ -213,88 +213,79 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transition: Anime timeline
|
|
||||||
*/
|
|
||||||
let timeline: AnimeTimelineInstance
|
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
// Setup animations
|
|
||||||
timeline = anime.timeline({
|
|
||||||
duration: 1600,
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
})
|
|
||||||
|
|
||||||
anime.set('.viewer__picture', {
|
|
||||||
opacity: 0,
|
|
||||||
})
|
|
||||||
anime.set('.viewer__picture.is-1', {
|
|
||||||
translateY: 24,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Photos
|
|
||||||
timeline.add({
|
|
||||||
targets: '.viewer__picture.is-1',
|
|
||||||
opacity: 1,
|
|
||||||
translateY: 0,
|
|
||||||
duration: 900,
|
|
||||||
}, 250)
|
|
||||||
timeline.add({
|
|
||||||
targets: '.viewer__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)
|
|
||||||
}, 500)
|
|
||||||
|
|
||||||
// Prev/Next buttons
|
|
||||||
timeline.add({
|
|
||||||
targets: '.viewer__controls button',
|
|
||||||
translateX (item: HTMLElement) {
|
|
||||||
let direction = item.classList.contains('prev') ? -1 : 1
|
|
||||||
return [16 * direction, 0]
|
|
||||||
},
|
|
||||||
opacity: [0, 1],
|
|
||||||
}, 450)
|
|
||||||
|
|
||||||
|
|
||||||
// Infos
|
|
||||||
timeline.add({
|
|
||||||
targets: '.viewer__info > *',
|
|
||||||
translateY: [24, 0],
|
|
||||||
opacity: [0, 1],
|
|
||||||
delay: anime.stagger(200)
|
|
||||||
}, 400)
|
|
||||||
|
|
||||||
|
|
||||||
anime.set('.viewer__index', {
|
|
||||||
opacity: 0
|
|
||||||
})
|
|
||||||
// Index
|
|
||||||
timeline.add({
|
|
||||||
targets: '.viewer__index',
|
|
||||||
opacity: 1,
|
|
||||||
duration: 900,
|
|
||||||
}, 600)
|
|
||||||
// Fly each number
|
|
||||||
timeline.add({
|
|
||||||
targets: '.viewer__index .char',
|
|
||||||
translateY: ['100%', 0],
|
|
||||||
delay: anime.stagger(200),
|
|
||||||
duration: 1000,
|
|
||||||
}, 700)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Transition in
|
/**
|
||||||
requestAnimationFrame(() => {
|
* Animations
|
||||||
timeline.play()
|
*/
|
||||||
|
// Setup animations
|
||||||
|
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||||
|
duration: 1600,
|
||||||
|
easing: 'easeOutQuart',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
anime.set('.viewer__picture', {
|
||||||
|
opacity: 0,
|
||||||
|
})
|
||||||
|
anime.set('.viewer__picture.is-1', {
|
||||||
|
translateY: 24,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Photos
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer__picture.is-1',
|
||||||
|
opacity: 1,
|
||||||
|
translateY: 0,
|
||||||
|
duration: 900,
|
||||||
|
}, 250)
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer__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)
|
||||||
|
}, 500)
|
||||||
|
|
||||||
|
// Prev/Next buttons
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer__controls button',
|
||||||
|
translateX (item: HTMLElement) {
|
||||||
|
let direction = item.classList.contains('prev') ? -1 : 1
|
||||||
|
return [16 * direction, 0]
|
||||||
|
},
|
||||||
|
opacity: [0, 1],
|
||||||
|
}, 450)
|
||||||
|
|
||||||
|
|
||||||
|
// Infos
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer__info > *',
|
||||||
|
translateY: [24, 0],
|
||||||
|
opacity: [0, 1],
|
||||||
|
delay: anime.stagger(200)
|
||||||
|
}, 400)
|
||||||
|
|
||||||
|
|
||||||
|
anime.set('.viewer__index', {
|
||||||
|
opacity: 0
|
||||||
|
})
|
||||||
|
// Index
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer__index',
|
||||||
|
opacity: 1,
|
||||||
|
duration: 900,
|
||||||
|
}, 600)
|
||||||
|
// Fly each number
|
||||||
|
timeline.add({
|
||||||
|
targets: '.viewer__index .char',
|
||||||
|
translateY: ['100%', 0],
|
||||||
|
delay: anime.stagger(200),
|
||||||
|
duration: 1000,
|
||||||
|
}, 700)
|
||||||
|
|
||||||
|
// Transition in
|
||||||
|
requestAnimationFrame(timeline.play)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/env'
|
|
||||||
import { navigating, page } from '$app/stores'
|
import { navigating, page } from '$app/stores'
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import anime from 'animejs'
|
import anime from 'animejs'
|
||||||
@@ -108,52 +107,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transition: Anime timeline
|
|
||||||
*/
|
|
||||||
let timeline: AnimeTimelineInstance
|
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
timeline = anime.timeline({
|
|
||||||
duration: 1600,
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
autoplay: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Title word
|
|
||||||
timeline.add({
|
|
||||||
targets: '.location-page__intro .word',
|
|
||||||
translateY: ['110%', 0],
|
|
||||||
delay: anime.stagger(200)
|
|
||||||
}, 200 + ($navigating ? DURATION.PAGE_IN : 0))
|
|
||||||
|
|
||||||
// Illustration
|
|
||||||
timeline.add({
|
|
||||||
targets: '.location-page__illustration',
|
|
||||||
scale: [1.06, 1],
|
|
||||||
opacity: [0, 1],
|
|
||||||
duration: 2400,
|
|
||||||
}, 400 + ($navigating ? DURATION.PAGE_IN : 0))
|
|
||||||
|
|
||||||
// Title of
|
|
||||||
timeline.add({
|
|
||||||
targets: '.location-page__intro .of',
|
|
||||||
opacity: [0, 1],
|
|
||||||
duration: 1200,
|
|
||||||
}, 1050 + ($navigating ? DURATION.PAGE_IN : 0))
|
|
||||||
|
|
||||||
// Description
|
|
||||||
timeline.add({
|
|
||||||
targets: '.location-page__description',
|
|
||||||
translateY: ['10%', 0],
|
|
||||||
opacity: [0, 1],
|
|
||||||
}, 900 + ($navigating ? DURATION.PAGE_IN : 0))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Photos IntersectionObserver
|
// Photos IntersectionObserver
|
||||||
observerPhotos = new IntersectionObserver(entries => {
|
observerPhotos = new IntersectionObserver(entries => {
|
||||||
@@ -186,11 +139,48 @@
|
|||||||
const existingPhotos = photosListEl.querySelectorAll('.house')
|
const existingPhotos = photosListEl.querySelectorAll('.house')
|
||||||
existingPhotos.forEach(el => observerPhotos.observe(el))
|
existingPhotos.forEach(el => observerPhotos.observe(el))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animations
|
||||||
|
*/
|
||||||
// Transition in
|
// Transition in
|
||||||
requestAnimationFrame(() => {
|
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||||
timeline.play()
|
duration: 1600,
|
||||||
|
easing: 'easeOutQuart',
|
||||||
|
autoplay: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Title word
|
||||||
|
timeline.add({
|
||||||
|
targets: '.location-page__intro .word',
|
||||||
|
translateY: ['110%', 0],
|
||||||
|
delay: anime.stagger(200)
|
||||||
|
}, 200 + ($navigating ? DURATION.PAGE_IN : 0))
|
||||||
|
|
||||||
|
// Illustration
|
||||||
|
timeline.add({
|
||||||
|
targets: '.location-page__illustration',
|
||||||
|
scale: [1.06, 1],
|
||||||
|
opacity: [0, 1],
|
||||||
|
duration: 2400,
|
||||||
|
}, 400 + ($navigating ? DURATION.PAGE_IN : 0))
|
||||||
|
|
||||||
|
// Title of
|
||||||
|
timeline.add({
|
||||||
|
targets: '.location-page__intro .of',
|
||||||
|
opacity: [0, 1],
|
||||||
|
duration: 1200,
|
||||||
|
}, 1050 + ($navigating ? DURATION.PAGE_IN : 0))
|
||||||
|
|
||||||
|
// Description
|
||||||
|
timeline.add({
|
||||||
|
targets: '.location-page__description',
|
||||||
|
translateY: ['10%', 0],
|
||||||
|
opacity: [0, 1],
|
||||||
|
}, 900 + ($navigating ? DURATION.PAGE_IN : 0))
|
||||||
|
|
||||||
|
requestAnimationFrame(timeline.play)
|
||||||
|
|
||||||
|
|
||||||
// Destroy
|
// Destroy
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/env'
|
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import anime from 'animejs'
|
import anime from 'animejs'
|
||||||
import type { AnimeTimelineInstance } from 'animejs'
|
import type { AnimeTimelineInstance } from 'animejs'
|
||||||
@@ -13,53 +12,43 @@
|
|||||||
export let data: any
|
export let data: any
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transition: Anime timeline
|
|
||||||
*/
|
|
||||||
let timeline: AnimeTimelineInstance
|
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
// Setup animations
|
|
||||||
timeline = anime.timeline({
|
|
||||||
duration: 1600,
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
autoplay: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
anime.set('.credits__heading > *, .credits__category > ul > li', {
|
|
||||||
opacity: 0,
|
|
||||||
translateY: 24,
|
|
||||||
})
|
|
||||||
anime.set('.credits__category', {
|
|
||||||
opacity: 0,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Elements
|
|
||||||
timeline.add({
|
|
||||||
targets: '.credits__heading > *, .credits__category',
|
|
||||||
opacity: 1,
|
|
||||||
translateY: 0,
|
|
||||||
delay: anime.stagger(350),
|
|
||||||
}, 500)
|
|
||||||
|
|
||||||
// Names
|
|
||||||
timeline.add({
|
|
||||||
targets: '.credits__category > ul > li',
|
|
||||||
opacity: 1,
|
|
||||||
translateY: 0,
|
|
||||||
delay: anime.stagger(350),
|
|
||||||
}, 1100)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Transition in
|
/**
|
||||||
requestAnimationFrame(() => {
|
* Animations
|
||||||
timeline.play()
|
*/
|
||||||
|
// Setup animations
|
||||||
|
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||||
|
duration: 1600,
|
||||||
|
easing: 'easeOutQuart',
|
||||||
|
autoplay: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
anime.set('.credits__heading > *, .credits__category > ul > li', {
|
||||||
|
opacity: 0,
|
||||||
|
translateY: 24,
|
||||||
|
})
|
||||||
|
anime.set('.credits__category', {
|
||||||
|
opacity: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Elements
|
||||||
|
timeline.add({
|
||||||
|
targets: '.credits__heading > *, .credits__category',
|
||||||
|
opacity: 1,
|
||||||
|
translateY: 0,
|
||||||
|
delay: anime.stagger(350),
|
||||||
|
}, 500)
|
||||||
|
|
||||||
|
// Names
|
||||||
|
timeline.add({
|
||||||
|
targets: '.credits__category > ul > li',
|
||||||
|
opacity: 1,
|
||||||
|
translateY: 0,
|
||||||
|
delay: anime.stagger(350),
|
||||||
|
}, 1100)
|
||||||
|
|
||||||
|
// Transition in
|
||||||
|
requestAnimationFrame(timeline.play)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/env'
|
|
||||||
import { page } from '$app/stores'
|
import { page } from '$app/stores'
|
||||||
import { goto } from '$app/navigation'
|
import { goto } from '$app/navigation'
|
||||||
import { getContext, onMount } from 'svelte'
|
import { getContext, onMount } from 'svelte'
|
||||||
@@ -245,42 +244,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transition: Anime timeline
|
|
||||||
*/
|
|
||||||
let timeline: AnimeTimelineInstance
|
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
// Setup animations
|
|
||||||
timeline = anime.timeline({
|
|
||||||
duration: 1600,
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
autoplay: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Reveal text
|
|
||||||
timeline.add({
|
|
||||||
targets: '.photos__intro .discover',
|
|
||||||
translateY: [16, 0],
|
|
||||||
opacity: [0, 1],
|
|
||||||
}, 900)
|
|
||||||
|
|
||||||
// Filters
|
|
||||||
timeline.add({
|
|
||||||
targets: '.photos__intro .filter',
|
|
||||||
translateY: [16, 0],
|
|
||||||
opacity: [0, 1],
|
|
||||||
complete ({ animatables }) {
|
|
||||||
const element = animatables[0].target
|
|
||||||
// Remove style to not interfere with CSS when scrolling back up over photos
|
|
||||||
element.removeAttribute('style')
|
|
||||||
}
|
|
||||||
}, 1300)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
/**
|
/**
|
||||||
* Observers
|
* Observers
|
||||||
@@ -316,11 +279,38 @@
|
|||||||
const existingPhotos = photosGridEl.querySelectorAll('.photo')
|
const existingPhotos = photosGridEl.querySelectorAll('.photo')
|
||||||
existingPhotos.forEach(el => observerPhotos.observe(el))
|
existingPhotos.forEach(el => observerPhotos.observe(el))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animations
|
||||||
|
*/
|
||||||
// Transition in
|
// Transition in
|
||||||
requestAnimationFrame(() => {
|
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||||
timeline.play()
|
duration: 1600,
|
||||||
|
easing: 'easeOutQuart',
|
||||||
|
autoplay: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Reveal text
|
||||||
|
timeline.add({
|
||||||
|
targets: '.photos__intro .discover',
|
||||||
|
translateY: [16, 0],
|
||||||
|
opacity: [0, 1],
|
||||||
|
}, 900)
|
||||||
|
|
||||||
|
// Filters
|
||||||
|
timeline.add({
|
||||||
|
targets: '.photos__intro .filter',
|
||||||
|
translateY: [16, 0],
|
||||||
|
opacity: [0, 1],
|
||||||
|
complete ({ animatables }) {
|
||||||
|
const element = animatables[0].target
|
||||||
|
// Remove style to not interfere with CSS when scrolling back up over photos
|
||||||
|
element.removeAttribute('style')
|
||||||
|
}
|
||||||
|
}, 1300)
|
||||||
|
|
||||||
|
// Play animation
|
||||||
|
requestAnimationFrame(timeline.play)
|
||||||
|
|
||||||
|
|
||||||
// Destroy
|
// Destroy
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/env'
|
|
||||||
import { getContext, onMount } from 'svelte'
|
import { getContext, onMount } from 'svelte'
|
||||||
import anime from 'animejs'
|
import anime from 'animejs'
|
||||||
import type { AnimeTimelineInstance } from 'animejs'
|
import type { AnimeTimelineInstance } from 'animejs'
|
||||||
@@ -25,44 +24,6 @@
|
|||||||
let scrolledPastIntro = false
|
let scrolledPastIntro = false
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transition: Anime timeline
|
|
||||||
*/
|
|
||||||
let timeline: AnimeTimelineInstance
|
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
timeline = anime.timeline({
|
|
||||||
duration: 1600,
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
autoplay: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Hero image
|
|
||||||
timeline.add({
|
|
||||||
targets: '.shop-page__background',
|
|
||||||
scale: [1.06, 1],
|
|
||||||
opacity: [0, 1],
|
|
||||||
duration: 2400,
|
|
||||||
}, 400)
|
|
||||||
|
|
||||||
// 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 > *',
|
|
||||||
translateY: [100, 0],
|
|
||||||
delay: anime.stagger(250),
|
|
||||||
}, 700)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Reveal the nav past the Intro
|
// Reveal the nav past the Intro
|
||||||
navObserver = new IntersectionObserver(entries => {
|
navObserver = new IntersectionObserver(entries => {
|
||||||
@@ -75,11 +36,42 @@
|
|||||||
})
|
})
|
||||||
navObserver.observe(introEl)
|
navObserver.observe(introEl)
|
||||||
|
|
||||||
// Transition in
|
|
||||||
requestAnimationFrame(() => {
|
/**
|
||||||
timeline.play()
|
* Animations
|
||||||
|
*/
|
||||||
|
// Setup animations
|
||||||
|
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||||
|
duration: 1600,
|
||||||
|
easing: 'easeOutQuart',
|
||||||
|
autoplay: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Hero image
|
||||||
|
timeline.add({
|
||||||
|
targets: '.shop-page__background',
|
||||||
|
scale: [1.06, 1],
|
||||||
|
opacity: [0, 1],
|
||||||
|
duration: 2400,
|
||||||
|
}, 400)
|
||||||
|
|
||||||
|
// 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 > *',
|
||||||
|
translateY: [100, 0],
|
||||||
|
delay: anime.stagger(250),
|
||||||
|
}, 700)
|
||||||
|
|
||||||
|
// Transition in
|
||||||
|
requestAnimationFrame(timeline.play)
|
||||||
|
|
||||||
|
|
||||||
// Destroy
|
// Destroy
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/env'
|
|
||||||
import { getContext, onMount } from 'svelte'
|
import { getContext, onMount } from 'svelte'
|
||||||
import anime from 'animejs'
|
import anime from 'animejs'
|
||||||
import type { AnimeTimelineInstance } from 'animejs'
|
import type { AnimeTimelineInstance } from 'animejs'
|
||||||
@@ -8,7 +7,6 @@
|
|||||||
import PageTransition from '$components/PageTransition.svelte'
|
import PageTransition from '$components/PageTransition.svelte'
|
||||||
import Metas from '$components/Metas.svelte'
|
import Metas from '$components/Metas.svelte'
|
||||||
import Image from '$components/atoms/Image.svelte'
|
import Image from '$components/atoms/Image.svelte'
|
||||||
import SiteTitle from '$components/atoms/SiteTitle.svelte'
|
|
||||||
import ButtonCart from '$components/atoms/ButtonCart.svelte'
|
import ButtonCart from '$components/atoms/ButtonCart.svelte'
|
||||||
import ShopLocationSwitcher from '$components/molecules/ShopLocationSwitcher.svelte'
|
import ShopLocationSwitcher from '$components/molecules/ShopLocationSwitcher.svelte'
|
||||||
import PostersGrid from '$components/organisms/PostersGrid.svelte'
|
import PostersGrid from '$components/organisms/PostersGrid.svelte'
|
||||||
@@ -20,46 +18,8 @@
|
|||||||
const { shop, shopLocations, posters } = getContext('shop')
|
const { shop, shopLocations, posters } = getContext('shop')
|
||||||
|
|
||||||
let introEl: HTMLElement
|
let introEl: HTMLElement
|
||||||
let navObserver: IntersectionObserver
|
var navObserver: IntersectionObserver
|
||||||
let scrolledPastIntro = false
|
var scrolledPastIntro = false
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transition: Anime timeline
|
|
||||||
*/
|
|
||||||
let timeline: AnimeTimelineInstance
|
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
timeline = anime.timeline({
|
|
||||||
duration: 1600,
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
autoplay: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Hero image
|
|
||||||
timeline.add({
|
|
||||||
targets: '.shop-page__background',
|
|
||||||
scale: [1.06, 1],
|
|
||||||
opacity: [0, 1],
|
|
||||||
duration: 2400,
|
|
||||||
}, 400)
|
|
||||||
|
|
||||||
// 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 > *',
|
|
||||||
translateY: [100, 0],
|
|
||||||
delay: anime.stagger(250),
|
|
||||||
}, 700)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
@@ -74,11 +34,42 @@
|
|||||||
})
|
})
|
||||||
navObserver.observe(introEl)
|
navObserver.observe(introEl)
|
||||||
|
|
||||||
// Transition in
|
|
||||||
requestAnimationFrame(() => {
|
/**
|
||||||
timeline.play()
|
* Animations
|
||||||
|
*/
|
||||||
|
// Setup animations
|
||||||
|
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||||
|
duration: 1600,
|
||||||
|
easing: 'easeOutQuart',
|
||||||
|
autoplay: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Hero image
|
||||||
|
timeline.add({
|
||||||
|
targets: '.shop-page__background',
|
||||||
|
scale: [1.06, 1],
|
||||||
|
opacity: [0, 1],
|
||||||
|
duration: 2400,
|
||||||
|
}, 400)
|
||||||
|
|
||||||
|
// 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 > *',
|
||||||
|
translateY: [100, 0],
|
||||||
|
delay: anime.stagger(250),
|
||||||
|
}, 700)
|
||||||
|
|
||||||
|
// Transition in
|
||||||
|
requestAnimationFrame(timeline.play)
|
||||||
|
|
||||||
|
|
||||||
// Destroy
|
// Destroy
|
||||||
return () => {
|
return () => {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts"> import { fade } from 'svelte/transition'
|
<script lang="ts">
|
||||||
import { browser } from '$app/env'
|
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import anime from 'animejs'
|
import anime from 'animejs'
|
||||||
@@ -16,51 +15,41 @@
|
|||||||
export let issues: any
|
export let issues: any
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transition: Anime timeline
|
|
||||||
*/
|
|
||||||
let timeline: AnimeTimelineInstance
|
|
||||||
|
|
||||||
if (browser) {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
// Setup animations
|
|
||||||
timeline = anime.timeline({
|
|
||||||
duration: 1600,
|
|
||||||
easing: 'easeOutQuart',
|
|
||||||
autoplay: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
anime.set('.subscribe__top > *, .subscribe__issues', {
|
|
||||||
opacity: 0,
|
|
||||||
translateY: 24,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Elements
|
|
||||||
timeline.add({
|
|
||||||
targets: '.subscribe__top > *, .subscribe__issues',
|
|
||||||
opacity: 1,
|
|
||||||
translateY: 0,
|
|
||||||
delay: anime.stagger(200),
|
|
||||||
}, 500)
|
|
||||||
|
|
||||||
// Reveal each issue
|
|
||||||
timeline.add({
|
|
||||||
targets: '.subscribe__issues .issue',
|
|
||||||
opacity: [0, 1],
|
|
||||||
translateY: [16, 0],
|
|
||||||
delay: anime.stagger(150),
|
|
||||||
duration: 1000,
|
|
||||||
}, 1000)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Transition in
|
/**
|
||||||
requestAnimationFrame(() => {
|
* Animations
|
||||||
timeline.play()
|
*/
|
||||||
|
// Setup animations
|
||||||
|
const timeline: AnimeTimelineInstance = anime.timeline({
|
||||||
|
duration: 1600,
|
||||||
|
easing: 'easeOutQuart',
|
||||||
|
autoplay: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
anime.set('.subscribe__top > *, .subscribe__issues', {
|
||||||
|
opacity: 0,
|
||||||
|
translateY: 24,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Elements
|
||||||
|
timeline.add({
|
||||||
|
targets: '.subscribe__top > *, .subscribe__issues',
|
||||||
|
opacity: 1,
|
||||||
|
translateY: 0,
|
||||||
|
delay: anime.stagger(200),
|
||||||
|
}, 500)
|
||||||
|
|
||||||
|
// Reveal each issue
|
||||||
|
timeline.add({
|
||||||
|
targets: '.subscribe__issues .issue',
|
||||||
|
opacity: [0, 1],
|
||||||
|
translateY: [16, 0],
|
||||||
|
delay: anime.stagger(150),
|
||||||
|
duration: 1000,
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
// Transition in
|
||||||
|
requestAnimationFrame(timeline.play)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ export const getRandomElement = (array: any[]): any => {
|
|||||||
/**
|
/**
|
||||||
* Get a DOM element's position
|
* Get a DOM element's position
|
||||||
*/
|
*/
|
||||||
export const getPosition = (node, scope?: HTMLElement) => {
|
export const getPosition = (node: any, scope?: HTMLElement) => {
|
||||||
const root = scope || document
|
const root = scope || document
|
||||||
let offsetTop = node.offsetTop
|
let offsetTop = node.offsetTop
|
||||||
let offsetLeft = node.offsetLeft
|
let offsetLeft = node.offsetLeft
|
||||||
|
|||||||
Reference in New Issue
Block a user