diff --git a/src/animations/Carousel.js b/src/animations/Carousel.js new file mode 100644 index 0000000..50f4ba4 --- /dev/null +++ b/src/animations/Carousel.js @@ -0,0 +1,56 @@ +import anime from 'animejs' +import ScrollOut from 'scroll-out' +import { animDuration } from '../utils/store' + + +/* +** Transition In +*/ +export const animateIn = () => { + // Card: Active + const cardActive = ScrollOut({ + once: true, + targets: '.gallery__photo--active', + onShown (el) { + anime({ + targets: el, + top: [32, 0], + duration: 1200, + delay: 650, + easing: 'easeOutQuart' + }) + } + }) + + // Card: Prev + const cardPrev = ScrollOut({ + once: true, + targets: '.gallery__photo--prev', + onShown (el) { + anime({ + targets: el, + top: [5, 0], + left: [-64, 0], + duration: 1200, + delay: 690, + easing: 'easeOutQuart' + }) + } + }) + + // Card: Prev + const cardNext = ScrollOut({ + once: true, + targets: '.gallery__photo--next', + onShown (el) { + anime({ + targets: el, + top: [5, 0], + left: [48, 0], + duration: 1200, + delay: 710, + easing: 'easeOutQuart' + }) + } + }) +} \ No newline at end of file diff --git a/src/animations/Locations.js b/src/animations/Locations.js new file mode 100644 index 0000000..0c471a1 --- /dev/null +++ b/src/animations/Locations.js @@ -0,0 +1,47 @@ +import anime from 'animejs' +import ScrollOut from 'scroll-out' +import { animDuration } from '../utils/store' + + +/* +** Transition In +*/ +export const animateIn = () => { + // Each location + const locations = ScrollOut({ + targets: '#locations_list .location', + onShown (el) { + // Timeline + const tl = anime.timeline({ + autoplay: false, + duration: 600, + delay: anime.stagger(200), + easing: 'easeOutQuart' + }) + + // Image + tl.add({ + targets: el.querySelector('img'), + scale: [1.3, 1], + opacity: [0, 1], + duration: 1800, + delay: 100 + }) + + // Name + tl.add({ + targets: el.querySelector('h3'), + translateY: ['100%', 0] + }, 300) + + // Country + tl.add({ + targets: el.querySelector('p'), + translateY: ['100%', 0] + }, 550) + + // Play + tl.play() + } + }) +} diff --git a/src/animations/TitleSite.js b/src/animations/TitleSite.js new file mode 100644 index 0000000..a2efdb9 --- /dev/null +++ b/src/animations/TitleSite.js @@ -0,0 +1,34 @@ +import anime from 'animejs' +import ScrollOut from 'scroll-out' +import { animDuration } from '../utils/store' + + +/* +** Transition In +*/ +export const animateIn = callback => { + // On scroll animation + const title = ScrollOut({ + once: true, + targets: '.title-location', + onShown (el) { + // Each letters + anime({ + targets: el.querySelectorAll('span'), + translateY: ['100%', 0], + delay: anime.stagger(40), + duration: 1000, + easing: 'easeOutQuart' + }) + + // Word in between + anime({ + targets: el.querySelectorAll('em span'), + opacity: [0, 1], + delay: anime.stagger(80, { start: 400 }), + duration: 1000, + easing: 'easeOutQuart' + }) + } + }) +} diff --git a/src/animations/Transition.js b/src/animations/Transition.js new file mode 100644 index 0000000..18cad46 --- /dev/null +++ b/src/animations/Transition.js @@ -0,0 +1,61 @@ +import anime from 'animejs' +import { animDuration, animDurationLong } from '../utils/store' + + +/* +** Transition In +*/ +export const animateIn = () => { + // Panel itself + const transition = anime({ + targets: '#transition', + height: ['100%', '100%'], + opacity: [0, 1], + duration: 200, + delay: 0, + easing: 'easeInOutQuart' + }) + // Globe icon + const globe = anime({ + targets: '#transition svg', + opacity: [0, 1], + duration: 200, + delay: 0, + easing: 'easeInOutQuart' + }) + +} + + +/* +** Transition Out +*/ +export const animateOut = callback => { + // Panel itself + const transition = anime({ + targets: '#transition', + height: ['100%', 0], + duration: animDurationLong, + delay: 800, + easing: 'easeInOutQuart', + complete: callback + }) + + // Title + const title = anime({ + targets: '#transition .title-location', + opacity: 0, + duration: 600, + delay: 1400, + easing: 'easeInOutQuart' + }) + + // Globe icon + const globe = anime({ + targets: '#transition svg', + opacity: 0, + duration: 600, + delay: 1400, + easing: 'easeInOutQuart' + }) +} diff --git a/src/utils/animations.js b/src/animations/crossfade.js similarity index 83% rename from src/utils/animations.js rename to src/animations/crossfade.js index a61dfec..23f2a90 100644 --- a/src/utils/animations.js +++ b/src/animations/crossfade.js @@ -1,10 +1,8 @@ -// import anime from 'animejs' import { crossfade } from 'svelte/transition' import { quartOut } from 'svelte/easing' - // Crossfade transition -export const [crossfadeSend, crossfadeReceive] = crossfade({ +export const [send, receive] = crossfade({ duration: d => Math.sqrt(d * 200), fallback(node, params) { diff --git a/src/animations/index.js b/src/animations/index.js new file mode 100644 index 0000000..d690e20 --- /dev/null +++ b/src/animations/index.js @@ -0,0 +1,121 @@ +import anime from 'animejs' +import ScrollOut from 'scroll-out' +import { animDuration } from '../utils/store' +import { debounce } from '../utils/functions' + + +/* +** Transition In +*/ +export const animateIn = () => { + // Title: Houses + const titleHouses = ScrollOut({ + once: true, + targets: '#title-houses', + onShown (el) { + // Reveal + anime({ + targets: el.querySelectorAll('span'), + translateY: ['-70%', 0], + delay: anime.stagger(80), + duration: animDuration, + easing: 'easeOutQuart' + }) + + // Parallax on scroll + const translate = anime.timeline({ + autoplay: false, + duration: animDuration + }) + translate.add({ + targets: el, + translateX: ['-3%', '-17%'], + easing: 'easeOutQuart', + duration: animDuration + }) + window.addEventListener('scroll', fn.debounce(event => { + translate.seek(translate.duration * (window.scrollY / 1000)) + }), 50) + } + }) + + // Intro: Description + const introDescription = ScrollOut({ + once: true, + targets: '#intro-description', + onShown (el) { + anime({ + targets: el.querySelectorAll('p, a'), + opacity: [0, 1], + translateY: [8, 0], + duration: animDuration, + delay: anime.stagger(200, { start: 400 }), + easing: 'easeOutQuart' + }) + } + }) + + // Intro: Carousel + const introCarousel = ScrollOut({ + once: true, + targets: '#intro-carousel', + onShown(el) { + anime({ + targets: el, + opacity: [0, 1], + translateY: [24, 0], + duration: animDuration, + delay: 650, + easing: 'easeOutQuart' + }) + } + }) + + // Title: Of + const titleOf = ScrollOut({ + once: true, + targets: '#title-of', + onShown (el) { + anime({ + targets: el.querySelectorAll('span'), + translateY: ['100%', 0], + delay: anime.stagger(70), + duration: animDuration, + easing: 'easeOutQuart' + }) + } + }) + + // Title: World + const titleWorld = ScrollOut({ + once: true, + targets: '#title-world', + onShown (el, ctx) { + anime({ + targets: el.querySelectorAll('span'), + translateY: ['100%', 0], + delay: anime.stagger(70), + duration: animDuration, + easing: 'easeOutQuart' + }) + + // Parallax on scroll + const translate = anime.timeline({ + autoplay: false, + duration: animDuration + }) + translate.add({ + targets: el, + translateX: ['4%', '-4%'], + easing: 'easeOutQuart', + duration: animDuration + }) + + if (ctx.visible) { + window.addEventListener('scroll', debounce(event => { + translate.seek(translate.duration * (window.scrollY / 1000)) + }), 35) + } + } + }) +} diff --git a/src/animations/page.js b/src/animations/page.js new file mode 100644 index 0000000..3baba56 --- /dev/null +++ b/src/animations/page.js @@ -0,0 +1,25 @@ +import anime from 'animejs' +import ScrollOut from 'scroll-out' +import { animDuration, animDurationLong } from '../utils/store' + + +/* +** Transition In +*/ +export const animateIn = () => { + // Simple fade + const page = ScrollOut({ + once: true, + targets: '.page', + onShown (el) { + anime({ + targets: '.page__part', + opacity: [0, 1], + translateY: [8, 0], + duration: 1800, + delay: anime.stagger(220, { start: animDurationLong * 0.3 }), + easing: 'easeOutQuart' + }) + } + }) +} diff --git a/src/animations/place.js b/src/animations/place.js new file mode 100644 index 0000000..38e00d3 --- /dev/null +++ b/src/animations/place.js @@ -0,0 +1,60 @@ +import anime from 'animejs' +// import ScrollOut from 'scroll-out' +import { animDuration } from '../utils/store' + + +/* +** Transition In +*/ +export const animateIn = () => { + const tl = anime.timeline({ + duration: 1800, + easing: 'easeOutQuart' + }) + + // Title: Houses + tl.add({ + targets: '.place__title_houses', + translateY: ['150%', 0], + duration: animDuration + }) + // Title: Of + tl.add({ + targets: '.place__title_of', + opacity: [0, 1], + duration: 800 + }, 550) + // Title: Place name + tl.add({ + targets: '.place__title_name', + translateY: ['150%', 0], + duration: animDuration + }, 200) + + // Switcher link + tl.add({ + targets: '.place__title .button-control', + scale: [0.95, 1], + opacity: [0, 1], + duration: animDuration + }, 700) + + // Illustration + tl.add({ + targets: '.place__illustration', + scale: [1.075, 1], + opacity: [0, 1], + duration: animDuration + }, 200) + + // Description + tl.add({ + targets: '.place__description', + opacity: [0, 1], + translateY: [24, 0], + duration: animDuration + }, 800) + + // Play + tl.play() +} diff --git a/src/atoms/TitleSite.svelte b/src/atoms/TitleSite.svelte index 8ed73bc..6d9e89e 100644 --- a/src/atoms/TitleSite.svelte +++ b/src/atoms/TitleSite.svelte @@ -1,17 +1,33 @@
{$site.explore_globe}
{$site.credits_text}
{$site.description}
@@ -117,11 +92,13 @@