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:
2020-03-06 14:22:51 +01:00
parent cd1033f97b
commit 9ffc210c02
27 changed files with 827 additions and 296 deletions

View File

@@ -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'
})
}
})
}

View File

@@ -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()
}
})
}

View File

@@ -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'
})
}
})
}

View File

@@ -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'
})
}

View File

@@ -0,0 +1,21 @@
import { crossfade } from 'svelte/transition'
import { quartOut } from 'svelte/easing'
// Crossfade transition
export const [send, receive] = 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}
`
}
}
})

121
src/animations/index.js Normal file
View File

@@ -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)
}
}
})
}

25
src/animations/page.js Normal file
View File

@@ -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'
})
}
})
}

60
src/animations/place.js Normal file
View File

@@ -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()
}