WIP attempt to fix page transitions, Several edits
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2020-04-02 16:07:16 +02:00
parent 6f409c5331
commit 730eb75457
34 changed files with 386 additions and 401 deletions

View File

@@ -51,12 +51,12 @@
"postcss": "^7.0.27", "postcss": "^7.0.27",
"postcss-load-config": "^2.1.0", "postcss-load-config": "^2.1.0",
"postcss-preset-env": "^6.7.0", "postcss-preset-env": "^6.7.0",
"rollup": "^2.3.1", "rollup": "^2.3.2",
"rollup-plugin-babel": "^4.4.0", "rollup-plugin-babel": "^4.4.0",
"rollup-plugin-eslint": "^7.0.0", "rollup-plugin-eslint": "^7.0.0",
"rollup-plugin-svelte": "^5.2.0", "rollup-plugin-svelte": "^5.2.0",
"rollup-plugin-terser": "^5.3.0", "rollup-plugin-terser": "^5.3.0",
"sapper": "^0.27.11", "sapper": "^0.27.12",
"svelte": "^3.20.1", "svelte": "^3.20.1",
"svelte-preprocess": "^3.7.1" "svelte-preprocess": "^3.7.1"
}, },

68
pnpm-lock.yaml generated
View File

@@ -15,10 +15,10 @@ devDependencies:
'@babel/plugin-transform-runtime': 7.9.0_@babel+core@7.9.0 '@babel/plugin-transform-runtime': 7.9.0_@babel+core@7.9.0
'@babel/preset-env': 7.9.0_@babel+core@7.9.0 '@babel/preset-env': 7.9.0_@babel+core@7.9.0
'@babel/runtime': 7.9.2 '@babel/runtime': 7.9.2
'@rollup/plugin-alias': 3.0.1_rollup@2.3.1 '@rollup/plugin-alias': 3.0.1_rollup@2.3.2
'@rollup/plugin-commonjs': 11.0.2_rollup@2.3.1 '@rollup/plugin-commonjs': 11.0.2_rollup@2.3.2
'@rollup/plugin-node-resolve': 7.1.1_rollup@2.3.1 '@rollup/plugin-node-resolve': 7.1.1_rollup@2.3.2
'@rollup/plugin-replace': 2.3.1_rollup@2.3.1 '@rollup/plugin-replace': 2.3.1_rollup@2.3.2
autoprefixer: 9.7.5 autoprefixer: 9.7.5
babel-plugin-module-resolver: 4.0.0 babel-plugin-module-resolver: 4.0.0
dotenv: 8.2.0 dotenv: 8.2.0
@@ -33,12 +33,12 @@ devDependencies:
postcss: 7.0.27 postcss: 7.0.27
postcss-load-config: 2.1.0 postcss-load-config: 2.1.0
postcss-preset-env: 6.7.0 postcss-preset-env: 6.7.0
rollup: 2.3.1 rollup: 2.3.2
rollup-plugin-babel: 4.4.0_@babel+core@7.9.0+rollup@2.3.1 rollup-plugin-babel: 4.4.0_@babel+core@7.9.0+rollup@2.3.2
rollup-plugin-eslint: 7.0.0 rollup-plugin-eslint: 7.0.0
rollup-plugin-svelte: 5.2.0_rollup@2.3.1+svelte@3.20.1 rollup-plugin-svelte: 5.2.0_rollup@2.3.2+svelte@3.20.1
rollup-plugin-terser: 5.3.0_rollup@2.3.1 rollup-plugin-terser: 5.3.0_rollup@2.3.2
sapper: 0.27.11_svelte@3.20.1 sapper: 0.27.12_svelte@3.20.1
svelte: 3.20.1 svelte: 3.20.1
svelte-preprocess: 3.7.1_svelte@3.20.1 svelte-preprocess: 3.7.1_svelte@3.20.1
lockfileVersion: 5.1 lockfileVersion: 5.1
@@ -892,23 +892,23 @@ packages:
dev: false dev: false
resolution: resolution:
integrity: sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== integrity: sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA==
/@rollup/plugin-alias/3.0.1_rollup@2.3.1: /@rollup/plugin-alias/3.0.1_rollup@2.3.2:
dependencies: dependencies:
rollup: 2.3.1 rollup: 2.3.2
slash: 3.0.0 slash: 3.0.0
dev: true dev: true
peerDependencies: peerDependencies:
rollup: ^1.20.0 rollup: ^1.20.0
resolution: resolution:
integrity: sha512-ReSy6iPl3GsWLMNeshXAfgItZFMoMOTYC7MZQQM5va4pqxiGgwl1xZUZfHW6zGyZPK+k8TBadxx+kdmepiUa+g== integrity: sha512-ReSy6iPl3GsWLMNeshXAfgItZFMoMOTYC7MZQQM5va4pqxiGgwl1xZUZfHW6zGyZPK+k8TBadxx+kdmepiUa+g==
/@rollup/plugin-commonjs/11.0.2_rollup@2.3.1: /@rollup/plugin-commonjs/11.0.2_rollup@2.3.2:
dependencies: dependencies:
'@rollup/pluginutils': 3.0.8_rollup@2.3.1 '@rollup/pluginutils': 3.0.8_rollup@2.3.2
estree-walker: 1.0.1 estree-walker: 1.0.1
is-reference: 1.1.4 is-reference: 1.1.4
magic-string: 0.25.7 magic-string: 0.25.7
resolve: 1.15.1 resolve: 1.15.1
rollup: 2.3.1 rollup: 2.3.2
dev: true dev: true
engines: engines:
node: '>= 8.0.0' node: '>= 8.0.0'
@@ -916,14 +916,14 @@ packages:
rollup: ^1.20.0 rollup: ^1.20.0
resolution: resolution:
integrity: sha512-MPYGZr0qdbV5zZj8/2AuomVpnRVXRU5XKXb3HVniwRoRCreGlf5kOE081isNWeiLIi6IYkwTX9zE0/c7V8g81g== integrity: sha512-MPYGZr0qdbV5zZj8/2AuomVpnRVXRU5XKXb3HVniwRoRCreGlf5kOE081isNWeiLIi6IYkwTX9zE0/c7V8g81g==
/@rollup/plugin-node-resolve/7.1.1_rollup@2.3.1: /@rollup/plugin-node-resolve/7.1.1_rollup@2.3.2:
dependencies: dependencies:
'@rollup/pluginutils': 3.0.8_rollup@2.3.1 '@rollup/pluginutils': 3.0.8_rollup@2.3.2
'@types/resolve': 0.0.8 '@types/resolve': 0.0.8
builtin-modules: 3.1.0 builtin-modules: 3.1.0
is-module: 1.0.0 is-module: 1.0.0
resolve: 1.15.1 resolve: 1.15.1
rollup: 2.3.1 rollup: 2.3.2
dev: true dev: true
engines: engines:
node: '>= 8.0.0' node: '>= 8.0.0'
@@ -931,20 +931,20 @@ packages:
rollup: ^1.20.0 rollup: ^1.20.0
resolution: resolution:
integrity: sha512-14ddhD7TnemeHE97a4rLOhobfYvUVcaYuqTnL8Ti7Jxi9V9Jr5LY7Gko4HZ5k4h4vqQM0gBQt6tsp9xXW94WPA== integrity: sha512-14ddhD7TnemeHE97a4rLOhobfYvUVcaYuqTnL8Ti7Jxi9V9Jr5LY7Gko4HZ5k4h4vqQM0gBQt6tsp9xXW94WPA==
/@rollup/plugin-replace/2.3.1_rollup@2.3.1: /@rollup/plugin-replace/2.3.1_rollup@2.3.2:
dependencies: dependencies:
'@rollup/pluginutils': 3.0.8_rollup@2.3.1 '@rollup/pluginutils': 3.0.8_rollup@2.3.2
magic-string: 0.25.7 magic-string: 0.25.7
rollup: 2.3.1 rollup: 2.3.2
dev: true dev: true
peerDependencies: peerDependencies:
rollup: ^1.20.0 rollup: ^1.20.0
resolution: resolution:
integrity: sha512-qDcXj2VOa5+j0iudjb+LiwZHvBRRgWbHPhRmo1qde2KItTjuxDVQO21rp9/jOlzKR5YO0EsgRQoyox7fnL7y/A== integrity: sha512-qDcXj2VOa5+j0iudjb+LiwZHvBRRgWbHPhRmo1qde2KItTjuxDVQO21rp9/jOlzKR5YO0EsgRQoyox7fnL7y/A==
/@rollup/pluginutils/3.0.8_rollup@2.3.1: /@rollup/pluginutils/3.0.8_rollup@2.3.2:
dependencies: dependencies:
estree-walker: 1.0.1 estree-walker: 1.0.1
rollup: 2.3.1 rollup: 2.3.2
dev: true dev: true
engines: engines:
node: '>= 8.0.0' node: '>= 8.0.0'
@@ -3792,11 +3792,11 @@ packages:
hasBin: true hasBin: true
resolution: resolution:
integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
/rollup-plugin-babel/4.4.0_@babel+core@7.9.0+rollup@2.3.1: /rollup-plugin-babel/4.4.0_@babel+core@7.9.0+rollup@2.3.2:
dependencies: dependencies:
'@babel/core': 7.9.0 '@babel/core': 7.9.0
'@babel/helper-module-imports': 7.8.3 '@babel/helper-module-imports': 7.8.3
rollup: 2.3.1 rollup: 2.3.2
rollup-pluginutils: 2.8.2 rollup-pluginutils: 2.8.2
dev: true dev: true
peerDependencies: peerDependencies:
@@ -3811,10 +3811,10 @@ packages:
dev: true dev: true
resolution: resolution:
integrity: sha512-u35kXiY11ULeNQGTlRkYx7uGJ/hS/Dx3wj8f9YVC3oMLTGU9fOqQJsAKYtBFZU3gJ8Vt3gu8ppB1vnKl+7gatQ== integrity: sha512-u35kXiY11ULeNQGTlRkYx7uGJ/hS/Dx3wj8f9YVC3oMLTGU9fOqQJsAKYtBFZU3gJ8Vt3gu8ppB1vnKl+7gatQ==
/rollup-plugin-svelte/5.2.0_rollup@2.3.1+svelte@3.20.1: /rollup-plugin-svelte/5.2.0_rollup@2.3.2+svelte@3.20.1:
dependencies: dependencies:
require-relative: 0.8.7 require-relative: 0.8.7
rollup: 2.3.1 rollup: 2.3.2
rollup-pluginutils: 2.8.2 rollup-pluginutils: 2.8.2
sourcemap-codec: 1.4.8 sourcemap-codec: 1.4.8
svelte: 3.20.1 svelte: 3.20.1
@@ -3824,11 +3824,11 @@ packages:
svelte: '*' svelte: '*'
resolution: resolution:
integrity: sha512-6B7gRsJC/rS/ATEy3J51McsNgNcDFibRQ/L3rHsDMUYeCDCm3dsw3KEqf3WaxX0ZdApzZ1XWcnTXGQlwVPYpnQ== integrity: sha512-6B7gRsJC/rS/ATEy3J51McsNgNcDFibRQ/L3rHsDMUYeCDCm3dsw3KEqf3WaxX0ZdApzZ1XWcnTXGQlwVPYpnQ==
/rollup-plugin-terser/5.3.0_rollup@2.3.1: /rollup-plugin-terser/5.3.0_rollup@2.3.2:
dependencies: dependencies:
'@babel/code-frame': 7.8.3 '@babel/code-frame': 7.8.3
jest-worker: 24.9.0 jest-worker: 24.9.0
rollup: 2.3.1 rollup: 2.3.2
rollup-pluginutils: 2.8.2 rollup-pluginutils: 2.8.2
serialize-javascript: 2.1.2 serialize-javascript: 2.1.2
terser: 4.6.7 terser: 4.6.7
@@ -3843,7 +3843,7 @@ packages:
dev: true dev: true
resolution: resolution:
integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==
/rollup/2.3.1: /rollup/2.3.2:
dev: true dev: true
engines: engines:
node: '>=10.0.0' node: '>=10.0.0'
@@ -3851,7 +3851,7 @@ packages:
optionalDependencies: optionalDependencies:
fsevents: 2.1.2 fsevents: 2.1.2
resolution: resolution:
integrity: sha512-BRjzOauORe+R0U0I6SkMTSG22nYmtztR/TaBl0SvbXgc3VAxBDrZoB6HROiK0S5px1pUBnLnjBkbzmVuwC9Q1Q== integrity: sha512-p66+fbfaUUOGE84sHXAOgfeaYQMslgAazoQMp//nlR519R61213EPFgrMZa48j31jNacJwexSAR1Q8V/BwGKBA==
/run-async/2.4.0: /run-async/2.4.0:
dependencies: dependencies:
is-promise: 2.1.0 is-promise: 2.1.0
@@ -3879,7 +3879,7 @@ packages:
dev: true dev: true
resolution: resolution:
integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
/sapper/0.27.11_svelte@3.20.1: /sapper/0.27.12_svelte@3.20.1:
dependencies: dependencies:
html-minifier: 4.0.0 html-minifier: 4.0.0
http-link-header: 1.0.2 http-link-header: 1.0.2
@@ -3892,7 +3892,7 @@ packages:
peerDependencies: peerDependencies:
svelte: ^3.5.0 svelte: ^3.5.0
resolution: resolution:
integrity: sha512-5EaPZhlc8OnyN3UCI6dRSM1Gz5sxyzLZG/1z5nMvZhg9Ng+rSvEvJx/rW/tSHcnQPa8or7+YcbfvQHKS5oPHiw== integrity: sha512-xTvPQMb9L3J34Jd+6jSFeiuT8eQZ2D5TXPeJI9VO7h8t5nB2w78ZNQ4IlEPHsCMT2LZNLozygTb2plE4qH2XeQ==
/sass-graph/2.2.4: /sass-graph/2.2.4:
dependencies: dependencies:
glob: 7.1.6 glob: 7.1.6
@@ -4555,12 +4555,12 @@ specifiers:
postcss: ^7.0.27 postcss: ^7.0.27
postcss-load-config: ^2.1.0 postcss-load-config: ^2.1.0
postcss-preset-env: ^6.7.0 postcss-preset-env: ^6.7.0
rollup: ^2.3.1 rollup: ^2.3.2
rollup-plugin-babel: ^4.4.0 rollup-plugin-babel: ^4.4.0
rollup-plugin-eslint: ^7.0.0 rollup-plugin-eslint: ^7.0.0
rollup-plugin-svelte: ^5.2.0 rollup-plugin-svelte: ^5.2.0
rollup-plugin-terser: ^5.3.0 rollup-plugin-terser: ^5.3.0
sapper: ^0.27.11 sapper: ^0.27.12
scroll-out: ^2.2.8 scroll-out: ^2.2.8
sirv: ^0.4.2 sirv: ^0.4.2
svelte: ^3.20.1 svelte: ^3.20.1

View File

@@ -1,56 +1,39 @@
import anime from 'animejs' import anime from 'animejs'
import ScrollOut from 'scroll-out' import ScrollOut from 'scroll-out'
// import { animDuration } from 'utils/store' import { transitionNormal, transitionDelay } from 'utils/store'
/* /*
** Transition In ** Transition In
*/ */
export const animateIn = scope => { export const animateIn = scope => {
// Card: Active // Timeline
const cardActive = ScrollOut({ const tl = anime.timeline({
once: true, easing: 'easeOutQuart',
targets: scope.querySelector('.gallery__photo--active'), duration: transitionNormal,
onShown (el) { delay: transitionDelay
anime({
targets: el,
top: [32, 0],
duration: 1200,
delay: 650,
easing: 'easeOutQuart'
})
}
}) })
// Photo: Active
tl.add({
targets: scope.querySelector('.is-active picture'),
translateY: [32, 0]
}, 400)
// Photo: Prev
tl.add({
targets: scope.querySelector('.is-prev picture'),
translateY: [8, 0],
translateX: [64, 0]
}, 550)
// Photo: Next
tl.add({
targets: scope.querySelector('.is-next picture'),
translateY: [8, 0],
translateX: [-48, 0]
}, 550)
// Card: Prev const carouselIn = ScrollOut({
const cardPrev = ScrollOut({
once: true, once: true,
targets: scope.querySelector('.gallery__photo--prev'), targets: scope,
onShown (el) { onShown: () => tl.restart()
anime({
targets: el,
top: [5, 0],
left: [-64, 0],
duration: 1200,
delay: 690,
easing: 'easeOutQuart'
})
}
})
// Card: Prev
const cardNext = ScrollOut({
once: true,
targets: scope.querySelector('.gallery__photo--next'),
onShown (el) {
anime({
targets: el,
top: [5, 0],
left: [48, 0],
duration: 1200,
delay: 710,
easing: 'easeOutQuart'
})
}
}) })
} }

View File

@@ -1,6 +1,6 @@
import anime from 'animejs' import anime from 'animejs'
import ScrollOut from 'scroll-out' import ScrollOut from 'scroll-out'
import { animDuration } from 'utils/store' import { transitionLong } from 'utils/store'
/* /*

View File

@@ -1,12 +1,12 @@
import anime from 'animejs' import anime from 'animejs'
import ScrollOut from 'scroll-out' import ScrollOut from 'scroll-out'
import { animDuration } from 'utils/store' import { transitionDelay } from 'utils/store'
/* /*
** Transition In ** Transition In
*/ */
export const animateIn = scope => { export const animateIn = (scope, init) => {
// On scroll animation // On scroll animation
const title = ScrollOut({ const title = ScrollOut({
once: true, once: true,
@@ -16,16 +16,16 @@ export const animateIn = scope => {
anime({ anime({
targets: el.querySelectorAll('span'), targets: el.querySelectorAll('span'),
translateY: ['100%', 0], translateY: ['100%', 0],
delay: anime.stagger(40), easing: 'easeOutQuart',
duration: 1000, delay: anime.stagger(40, { start: init ? 0 : transitionDelay }),
easing: 'easeOutQuart' duration: 1000
}) })
// Word in between // Word in between
anime({ anime({
targets: el.querySelectorAll('em span'), targets: el.querySelectorAll('em span'),
opacity: [0, 1], opacity: [0, 1],
delay: anime.stagger(80, { start: 400 }), delay: anime.stagger(80, { start: (init ? 0 : transitionDelay) + 400 }),
duration: 1000, duration: 1000,
easing: 'easeOutQuart' easing: 'easeOutQuart'
}) })

View File

@@ -1,32 +1,34 @@
import anime from 'animejs' import anime from 'animejs'
import { animDuration, animDurationLong } from 'utils/store' import { transitionNormal, transitionLong, transitionPanelIn } from 'utils/store'
/* /*
** Transition In ** Transition In
*/ */
export const animateIn = scope => { export const animateIn = scope => {
// Panel itself const tl = anime.timeline({
const transition = anime({ duration: transitionPanelIn,
targets: scope.querySelector('.transition__background'),
scaleY: [1, 1],
opacity: [0, 1],
duration: 400,
easing: 'easeInOutQuart', easing: 'easeInOutQuart',
begin () { begin: () => {
// Show the panel // Show the panel
scope.classList.remove('hidden') scope.classList.remove('hidden')
} }
}) })
// Panel itself
tl.add({
targets: scope.querySelector('.transition__background'),
scaleY: [1, 1],
opacity: [0, 1],
duration: transitionPanelIn
}, 0)
// Globe icon // Globe icon
const globe = anime({ tl.add({
targets: scope.querySelector('svg'), targets: scope.querySelector('svg'),
opacity: [0, 1], opacity: [0, 1],
translateY: ['16px', 0], translateY: ['3vh', 0],
duration: 400, duration: transitionPanelIn
easing: 'easeInOutQuart' }, 0)
})
} }
@@ -34,14 +36,9 @@ export const animateIn = scope => {
** Transition Out ** Transition Out
*/ */
export const animateOut = (scope, callback) => { export const animateOut = (scope, callback) => {
// Background const tl = anime.timeline({
const background = anime({
targets: scope.querySelector('.transition__background'),
scaleY: [1, 0],
duration: animDurationLong,
delay: 800,
easing: 'easeInOutQuart', easing: 'easeInOutQuart',
complete () { complete: () => {
// Hide the panel // Hide the panel
scope.classList.add('hidden') scope.classList.add('hidden')
@@ -50,23 +47,29 @@ export const animateOut = (scope, callback) => {
} }
}) })
// Background
tl.add({
targets: scope.querySelector('.transition__background'),
scaleY: [1, 0],
duration: transitionLong
}, 600)
// Title // Title
const title = anime({ tl.add({
targets: scope.querySelector('.title-location'), targets: scope.querySelector('.title-location'),
opacity: [1, 0], opacity: [1, 0],
translateY: [0, '-50vh'], translateY: [0, '-50vh'],
duration: animDuration, duration: transitionNormal
delay: 1000, }, 850)
easing: 'easeInOutQuart'
})
// Globe icon // Globe icon
const globe = anime({ tl.add({
targets: scope.querySelector('svg'), targets: scope.querySelector('svg'),
opacity: [1, 0], opacity: [1, 0],
translateY: [0, '-50vh'], translateY: [0, '-50vh'],
duration: animDuration, duration: transitionNormal
delay: 1000, }, 850)
easing: 'easeInOutQuart'
}) // Play
tl.play()
} }

View File

@@ -1,6 +1,6 @@
import anime from 'animejs' import anime from 'animejs'
import ScrollOut from 'scroll-out' import ScrollOut from 'scroll-out'
import { animDuration } from 'utils/store' import { transitionNormal, transitionLong, transitionDelay } from 'utils/store'
import { throttle, parallaxAnime } from 'utils/functions' import { throttle, parallaxAnime } from 'utils/functions'
@@ -9,67 +9,65 @@ import { throttle, parallaxAnime } from 'utils/functions'
*/ */
export const animateIn = () => { export const animateIn = () => {
// Title: Houses // Title: Houses
const titleHouses = ScrollOut({ // const titleHouses = ScrollOut({
once: true, // once: true,
targets: '#title-houses', // targets: '#title-houses',
onShown (el) { // onShown (el) {
// Reveal each letter // Reveal each letter
anime({ anime({
targets: el.querySelectorAll('span'), targets: document.querySelectorAll('#title-houses span'),
translateY: ['-70%', 0], translateY: ['-70%', 0],
delay: anime.stagger(80), delay: anime.stagger(80, { start: transitionDelay }),
duration: animDuration, duration: transitionNormal,
easing: 'easeOutQuart' easing: 'easeOutQuart'
}) })
// Parallax on scroll // Parallax on scroll
const translate = anime({ const translate = anime({
targets: el, targets: '#title-houses',
translateX: ['7%', '-15%'], translateX: ['7%', '-15%'],
easing: 'linear', easing: 'linear',
autoplay: false, autoplay: false,
duration: animDuration duration: transitionNormal
})
window.addEventListener('scroll', throttle(() => parallaxAnime(el, translate), 10))
setTimeout(() => parallaxAnime(el, translate), 50)
},
onHidden () {
window.removeEventListener('scroll', parallaxAnime)
}
}) })
window.addEventListener('scroll', throttle(() => parallaxAnime(document.getElementById('title-houses'), translate), 10))
setTimeout(() => parallaxAnime(document.getElementById('title-houses'), translate), 50)
// },
// onHidden: () => window.removeEventListener('scroll', parallaxAnime)
// })
// Intro: Description // Intro: Description
const introDescription = ScrollOut({ // const introDescription = ScrollOut({
once: true, // once: true,
targets: '#intro-description', // targets: '#intro-description',
onShown (el) { // onShown (el) {
anime({ anime({
targets: el.querySelectorAll('p, a'), targets: '#intro-description p, #intro-description a',
opacity: [0, 1], opacity: [0, 1],
translateY: [8, 0], translateY: [8, 0],
duration: animDuration, easing: 'easeOutQuart',
delay: anime.stagger(200, { start: 400 }), duration: transitionNormal,
easing: 'easeOutQuart' delay: anime.stagger(200, { start: transitionDelay + 400 })
})
}
}) })
// }
// })
// Intro: Carousel // Intro: Carousel
const introCarousel = ScrollOut({ // const introCarousel = ScrollOut({
once: true, // once: true,
targets: '#intro-carousel', // targets: '#intro-carousel',
onShown (el) { // onShown (el) {
anime({ anime({
targets: el, targets: '#intro-carousel',
opacity: [0, 1], opacity: [0, 1],
translateY: [24, 0], translateY: [24, 0],
duration: animDuration,
delay: 650,
easing: 'easeOutQuart', easing: 'easeOutQuart',
complete: () => el.removeAttribute('style') duration: transitionNormal,
}) delay: transitionDelay + 600,
} complete: event => event.animatables[0].target.removeAttribute('style')
}) })
// }
// })
// Title: Of // Title: Of
const titleOf = ScrollOut({ const titleOf = ScrollOut({
@@ -79,9 +77,9 @@ export const animateIn = () => {
anime({ anime({
targets: el.querySelectorAll('span'), targets: el.querySelectorAll('span'),
translateY: ['100%', 0], translateY: ['100%', 0],
easing: 'easeOutQuart',
delay: anime.stagger(70), delay: anime.stagger(70),
duration: animDuration, duration: transitionNormal
easing: 'easeOutQuart'
}) })
} }
}) })
@@ -94,9 +92,9 @@ export const animateIn = () => {
anime({ anime({
targets: el.querySelectorAll('span'), targets: el.querySelectorAll('span'),
translateY: ['100%', 0], translateY: ['100%', 0],
easing: 'easeOutQuart',
delay: anime.stagger(70), delay: anime.stagger(70),
duration: animDuration, duration: transitionNormal
easing: 'easeOutQuart'
}) })
// Parallax on scroll // Parallax on scroll
@@ -105,14 +103,27 @@ export const animateIn = () => {
translateX: ['5%', '-3%'], translateX: ['5%', '-3%'],
easing: 'linear', easing: 'linear',
autoplay: false, autoplay: false,
duration: animDuration duration: transitionNormal
}) })
window.addEventListener('scroll', throttle(() => parallaxAnime(el, translate), 10)) window.addEventListener('scroll', throttle(() => parallaxAnime(el, translate), 10))
setTimeout(() => parallaxAnime(el, translate), 50) setTimeout(() => parallaxAnime(el, translate), 50)
}, },
onHidden() { onHidden: () => window.removeEventListener('scroll', parallaxAnime)
window.removeEventListener('scroll', parallaxAnime) })
} }
/*
** Transition Out
*/
export const animateOut = () => {
anime({
targets: document.querySelector('#title-houses'),
translateY: ['-70%', 0],
opacity: [1, 0],
duration: transitionNormal,
easing: 'easeOutQuart'
}) })
} }

View File

@@ -1,25 +1,25 @@
import anime from 'animejs' import anime from 'animejs'
import ScrollOut from 'scroll-out' import ScrollOut from 'scroll-out'
import { animDuration, animDurationLong } from 'utils/store' import { transitionNormal, transitionDelay } from 'utils/store'
/* /*
** Transition In ** Transition In
*/ */
export const animateIn = () => { export const animateIn = () => {
// Simple fade // Simple slide and fade on each part of the page
const page = ScrollOut({ // const page = ScrollOut({
once: true, // once: true,
targets: '.page', // targets: '.page',
onShown (el) { // onShown (el) {
anime({ anime({
targets: '.page__part', targets: document.querySelectorAll('.page__part'),
opacity: [0, 1], opacity: [0, 1],
translateY: [8, 0], translateY: [8, 0],
duration: 1800, easing: 'easeOutQuart',
delay: anime.stagger(220, { start: animDurationLong * 0.3 }), duration: transitionNormal,
easing: 'easeOutQuart' delay: anime.stagger(220, { start: transitionDelay }),
})
}
}) })
// }
// })
} }

View File

@@ -1,6 +1,6 @@
import anime from 'animejs' import anime from 'animejs'
// import ScrollOut from 'scroll-out' // import ScrollOut from 'scroll-out'
import { animDuration } from 'utils/store' import { transitionNormal, transitionDelay } from 'utils/store'
/* /*
@@ -9,7 +9,7 @@ import { animDuration } from 'utils/store'
export const animateIn = () => { export const animateIn = () => {
const tl = anime.timeline({ const tl = anime.timeline({
duration: 1800, duration: 1800,
delay: 1800, delay: transitionDelay, // Delay in AnimeJS waits to run but sets the starting style as opposed to a setTimeout
easing: 'easeOutQuart' easing: 'easeOutQuart'
}) })
@@ -17,27 +17,27 @@ export const animateIn = () => {
tl.add({ tl.add({
targets: '.place__title_houses', targets: '.place__title_houses',
translateY: ['150%', 0], translateY: ['150%', 0],
duration: animDuration duration: transitionNormal
}) }, 200)
// Title: Of // Title: Of
tl.add({ tl.add({
targets: '.place__title_of', targets: '.place__title_of',
opacity: [0, 1], opacity: [0, 1],
duration: 800 duration: transitionNormal
}, 550) }, 800)
// Title: Place name // Title: Place name
tl.add({ tl.add({
targets: '.place__title_name', targets: '.place__title_name',
translateY: ['150%', 0], translateY: ['150%', 0],
duration: animDuration duration: transitionNormal
}, 200) }, 350)
// Switcher link // Switcher link
tl.add({ tl.add({
targets: '.place__title .button-control', targets: '.place__title .button-control',
scale: [0.95, 1], scale: [0.95, 1],
opacity: [0, 1], opacity: [0, 1],
duration: animDuration duration: transitionNormal
}, 700) }, 700)
// Illustration // Illustration
@@ -45,7 +45,7 @@ export const animateIn = () => {
targets: '.place__illustration', targets: '.place__illustration',
scale: [1.075, 1], scale: [1.075, 1],
opacity: [0, 1], opacity: [0, 1],
duration: animDuration duration: transitionNormal
}, 200) }, 200)
// Description // Description
@@ -53,8 +53,8 @@ export const animateIn = () => {
targets: '.place__description', targets: '.place__description',
opacity: [0, 1], opacity: [0, 1],
translateY: [24, 0], translateY: [24, 0],
duration: animDuration duration: transitionNormal
}, 800) }, 650)
// Play // Play
tl.play() tl.play()

View File

@@ -1,5 +1,5 @@
import anime from 'animejs' import anime from 'animejs'
import { animDuration } from 'utils/store' import { transitionNormal } from 'utils/store'
/* /*
@@ -10,7 +10,7 @@ export const animateIn = () => {
anime({ anime({
targets: '.viewer__top p, .viewer__top .buttons a', targets: '.viewer__top p, .viewer__top .buttons a',
translateY: [-32, 0], translateY: [-32, 0],
duration: animDuration, duration: transitionNormal,
delay: anime.stagger(150, { start: 600 }), delay: anime.stagger(150, { start: 600 }),
easing: 'easeOutQuart' easing: 'easeOutQuart'
}) })
@@ -20,7 +20,7 @@ export const animateIn = () => {
targets: '.viewer .carousel', targets: '.viewer .carousel',
opacity: [0, 1], opacity: [0, 1],
translateY: window.innerWidth >= 768 ? [32, 0] : ['-33%', '-37%'], translateY: window.innerWidth >= 768 ? [32, 0] : ['-33%', '-37%'],
duration: animDuration, duration: transitionNormal,
delay: 300, delay: 300,
easing: 'easeOutQuart' easing: 'easeOutQuart'
}) })
@@ -30,7 +30,7 @@ export const animateIn = () => {
targets: '.viewer .carousel__number_column', targets: '.viewer .carousel__number_column',
opacity: [0, 1], opacity: [0, 1],
marginTop: [24, 0], marginTop: [24, 0],
duration: animDuration, duration: transitionNormal,
delay: anime.stagger(100, { start: 450 }), delay: anime.stagger(100, { start: 450 }),
easing: 'easeOutQuart' easing: 'easeOutQuart'
}) })

View File

@@ -15,7 +15,7 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width={width} viewBox="0 0 56 75" width={width} viewBox="0 0 56 75"
fill={color} fill={color}
class="icon-globe" class:icon-svg--animated={animated} class="icon-svg icon-globe" class:is-animated={animated}
> >
<defs> <defs>
<clipPath id={randomId}> <clipPath id={randomId}>

View File

@@ -15,7 +15,7 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width={width} viewBox="0 0 56 56" width={width} viewBox="0 0 56 56"
fill={color} fill={color}
class="icon-globe icon-globe--small" class:icon-svg--animated={animated} class="icon-svg icon-globe icon-globe--small" class:is-animated={animated}
> >
<defs> <defs>
<clipPath id={randomId}> <clipPath id={randomId}>

View File

@@ -5,7 +5,8 @@
// Animations // Animations
import { animateIn } from 'animations/TitleSite' import { animateIn } from 'animations/TitleSite'
// Variables // Props and variables
export let init = false
let scope let scope
let mounted = false let mounted = false
@@ -14,8 +15,8 @@
** Run code on component mount ** Run code on component mount
*/ */
onMount(() => { onMount(() => {
animateIn(scope, init)
mounted = true mounted = true
animateIn(scope)
}) })
</script> </script>

View File

@@ -56,7 +56,7 @@
// Hover on controls // Hover on controls
const hoverPhoto = event => { const hoverPhoto = event => {
const button = event.currentTarget.querySelector('button') const button = event.currentTarget.querySelector('button')
const photoActive = scope.querySelector('.gallery__photo--active') const photoActive = scope.querySelector('.is-active')
let photoToHover let photoToHover
if (event.currentTarget.dataset.to === 'prev') { if (event.currentTarget.dataset.to === 'prev') {
@@ -114,7 +114,7 @@
*/ */
onMount(() => { onMount(() => {
// Entering transition // Entering transition
if (photos.length) { if (photos) {
animateIn(scope) animateIn(scope)
} }
@@ -134,7 +134,7 @@
<svelte:window on:keydown={keyboardNav} /> <svelte:window on:keydown={keyboardNav} />
{#if photos.length} {#if photos}
<div class="carousel" <div class="carousel"
bind:this={scope} bind:this={scope}
on:swipe={event => swipe(event.detail.directions)} on:swipe={event => swipe(event.detail.directions)}
@@ -143,18 +143,20 @@
<div class="gallery"> <div class="gallery">
<div class="gallery__images"> <div class="gallery__images">
{#each photos as { id, name, location, image }, index} {#each photos as { id, name, location, image }, index}
<picture class="gallery__photo" <div class="gallery__photo"
class:gallery__photo--prev={id === prevPhoto.id} class:is-prev={id === prevPhoto.id}
class:gallery__photo--active={id === currentPhoto.id} class:is-active={id === currentPhoto.id}
class:gallery__photo--next={id === nextPhoto.id} class:is-next={id === nextPhoto.id}
on:click={openFullscreen} on:click={openFullscreen}
> >
<picture class="gallery__picture">
<source media="(min-width: 968px)" srcset={getThumbnail(image.private_hash, 1400)}> <source media="(min-width: 968px)" srcset={getThumbnail(image.private_hash, 1400)}>
<source media="(min-width: 800px)" srcset={getThumbnail(image.private_hash, 900)}> <source media="(min-width: 800px)" srcset={getThumbnail(image.private_hash, 900)}>
<source media="(min-width: 500px)" srcset={getThumbnail(image.private_hash, 600)}> <source media="(min-width: 500px)" srcset={getThumbnail(image.private_hash, 600)}>
<source media="(min-width: 300px)" srcset={getThumbnail(image.private_hash, 400)}> <source media="(min-width: 300px)" srcset={getThumbnail(image.private_hash, 400)}>
<img src="{getThumbnail(image.private_hash, 900)}" alt="{name}, {location.name}, {location.country.name}"> <img src="{getThumbnail(image.private_hash, 900)}" alt="{name}, {location.name}, {location.country.name}">
</picture> </picture>
</div>
{/each} {/each}
</div> </div>
@@ -189,9 +191,9 @@
<div class="carousel__locations"> <div class="carousel__locations">
{#each photos as { id, name, location }, index} {#each photos as { id, name, location }, index}
<div class="carousel__location style-location" <div class="carousel__location style-location"
class:carousel__location--prev={id === prevPhoto.id} class:is-prev={id === prevPhoto.id}
class:carousel__location--active={id === currentPhoto.id} class:is-active={id === currentPhoto.id}
class:carousel__location--next={id === nextPhoto.id} class:is-next={id === nextPhoto.id}
> >
<p class="street">{name}</p> <p class="street">{name}</p>
<p class="state style-caps style-caps--transparent"> <p class="state style-caps style-caps--transparent">

View File

@@ -70,7 +70,8 @@
site, site,
continents, continents,
countries, countries,
locations locations,
pageReady
} from 'utils/store' } from 'utils/store'
// Components // Components
@@ -106,7 +107,9 @@
<link rel="canonical" href={`https://${$page.host}${$page.path}`} /> <link rel="canonical" href={`https://${$page.host}${$page.path}`} />
</svelte:head> </svelte:head>
<main class="housesof" style="opacity: { $pageReady ? 1 : 0}">
<slot></slot> <slot></slot>
</main>
{#if process.env.CONFIG.TRANSITION === 'true'} {#if process.env.CONFIG.TRANSITION === 'true'}
<Transition /> <Transition />

View File

@@ -75,9 +75,9 @@
{/each} {/each}
</div> </div>
{/if} {/if}
</div>
<InteractiveGlobe type="part" /> <InteractiveGlobe type="part" />
</div>
<Footer /> <Footer />
</section> </section>

View File

@@ -24,7 +24,7 @@
</script> </script>
<script> <script>
import { onMount } from 'svelte' import { onMount, onDestroy } from 'svelte'
import { stores } from '@sapper/app' import { stores } from '@sapper/app'
import { import {
apiEndpoints, apiEndpoints,
@@ -56,7 +56,7 @@
pageTransition.onAnimationEnd = animateIn pageTransition.onAnimationEnd = animateIn
// Props and variables // Props and variables
export let photos export let photos = ''
const { page } = stores() const { page } = stores()
// Reset current location if existing // Reset current location if existing
@@ -106,9 +106,10 @@
</div> </div>
<div id="intro-carousel"> <div id="intro-carousel">
{#if photos}
<Carousel {photos} /> <Carousel {photos} />
<Fullscreen /> <Fullscreen />
{/if}
</div> </div>
</section> </section>

View File

@@ -6,7 +6,8 @@
// Load photos // Load photos
const fields = [ const fields = [
'id', 'name', 'slug', 'date', 'image.private_hash', 'id', 'name', 'slug', 'date', 'image.private_hash',
'location.id', 'location.name', 'location.slug', 'location.region', 'location.country.name', 'location.country.slug', 'location.id', 'location.name', 'location.slug', 'location.region',
'location.country.name', 'location.country.slug',
'created_on', 'modified_on' 'created_on', 'modified_on'
].join(',') ].join(',')
const sort = ['-created_on', 'name'].join(',') const sort = ['-created_on', 'name'].join(',')
@@ -58,6 +59,7 @@
// Update current location // Update current location
const location = $locations.find(loc => loc.slug === $page.params.place) const location = $locations.find(loc => loc.slug === $page.params.place)
const { description, country, illustration_desktop, illustration_mobile } = location
currentLocation.set(location) currentLocation.set(location)
currentPhotos.set(photos) currentPhotos.set(photos)
@@ -96,12 +98,12 @@
</script> </script>
<svelte:head> <svelte:head>
<title>{$site.seo_name} Beautiful houses of {location.name}, {location.country.name}</title> <title>{$site.seo_name} Beautiful houses of {location.name}, {country.name}</title>
<meta name="description" content="{$site.seo_name} {location.name} {location.description}"> <meta name="description" content="{$site.seo_name} {location.name} {description}">
<SocialMetas <SocialMetas
url="https://{$page.host}/location/{location.country.slug}/{location.slug}" url="https://{$page.host}/location/{country.slug}/{location.slug}"
title="{$site.seo_name} Beautiful houses of {location.name}, {location.country.name}" title="{$site.seo_name} Beautiful houses of {location.name}, {country.name}"
description="{$site.seo_name} {location.name} {location.description}" description="{$site.seo_name} {location.name} {description}"
image={latestPhoto ? getThumbnail(latestPhoto.image.private_hash, 1200, 630) : null} image={latestPhoto ? getThumbnail(latestPhoto.image.private_hash, 1200, 630) : null}
/> />
</svelte:head> </svelte:head>
@@ -135,17 +137,17 @@
<div class="wrapper"> <div class="wrapper">
<p>{$site.description}</p> <p>{$site.description}</p>
{#if location.description} {#if description}
<p> <p>
Houses Of Houses Of
<LinkChange href="/choose" text={location.name} noScroll="true"> <LinkChange href="/choose" text={location.name} noScroll="true">
<IconGlobeSmall width="14" color="#999" /> <IconGlobeSmall width="14" color="#999" />
</LinkChange> </LinkChange>
{location.description} {description}
</p> </p>
{/if} {/if}
{#if photos.length} {#if photos}
<p class="updated style-caps"> <p class="updated style-caps">
<strong>Updated</strong> <strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time> <time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
@@ -157,9 +159,9 @@
</div> </div>
</div> </div>
{#if location.illustration_desktop && location.illustration_mobile} {#if illustration_desktop && illustration_mobile}
<div class="place__illustration" <div class="place__illustration"
style="--url-desktop: url({location.illustration_desktop.full_url}); --url-mobile: url({location.illustration_mobile.full_url});" style="--url-desktop: url({illustration_desktop.full_url}); --url-mobile: url({illustration_mobile.full_url});"
/> />
{/if} {/if}
</section> </section>
@@ -169,7 +171,7 @@
<aside class="photos__side"> <aside class="photos__side">
<Switcher type="switcher--side" /> <Switcher type="switcher--side" />
{#if photos.length} {#if photos}
<p class="updated style-caps"> <p class="updated style-caps">
<strong>Updated</strong> <strong>Updated</strong>
<time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time> <time datetime={dateUpdatedDatetime} title={dateUpdatedFull}>{dateUpdatedRelative}</time>
@@ -178,7 +180,7 @@
</aside> </aside>
</div> </div>
{#if photos.length} {#if photos}
<div class="photos__view wrap"> <div class="photos__view wrap">
{#each paginatedPhotos as photo, index} {#each paginatedPhotos as photo, index}
<Photo <Photo

View File

@@ -78,7 +78,7 @@
background-color: $color-secondary; background-color: $color-secondary;
svg { svg {
fill: #fff !important; fill: #fff;
} }
.anim { .anim {
animation-play-state: running; animation-play-state: running;

View File

@@ -19,7 +19,7 @@
} }
// Animate by default // Animate by default
&--animated { &.is-animated {
.anim { .anim {
animation-play-state: running; animation-play-state: running;
} }

View File

@@ -0,0 +1,5 @@
// Main page
.housesof {
transition: opacity 0.4s $ease-quart;
will-change: opacity;
}

View File

@@ -1,6 +1,11 @@
// Carousel // Carousel
.carousel { .carousel {
background-color: $color-primary; background-color: $color-primary;
overflow: hidden;
@include breakpoint (sm) {
overflow: visible;
}
.wrap { .wrap {
max-width: 1280px; max-width: 1280px;
@@ -52,7 +57,6 @@
&__photo { &__photo {
$duration: 1s; $duration: 1s;
opacity: 0; opacity: 0;
overflow: hidden;
position: absolute; position: absolute;
z-index: -1; z-index: -1;
top: 0; top: 0;
@@ -60,21 +64,78 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
transform: scale($scale); transform: scale($scale);
box-shadow: 0 pxVW(15) pxVW(60) rgba(#000, 0.3);
transition: transform $duration $ease-quart, opacity ($duration / 2) $ease-quart; transition: transform $duration $ease-quart, opacity ($duration / 2) $ease-quart;
will-change: transform, opacity, top, left; will-change: transform, opacity, top, left;
@include breakpoint (sm) { // Active photo
border-radius: $radius; &.is-active {
} opacity: 1;
z-index: 10;
transform: scale(1);
img { img {
opacity: 0; opacity: 1;
position: relative; }
z-index: 1; }
// Previous & next photo
&.is-prev, &.is-next {
opacity: 1;
img {
opacity: 1;
}
picture:before {
@include breakpoint (sm) {
opacity: 0.4;
}
}
}
// Previous photo
&.is-prev {
z-index: 9;
transform: translate(-40%, 0) scale(0.85);
@include breakpoint (sm) {
z-index: 8;
transform: translate(-$distance, -1%) rotate(-$angle) scale($scale);
}
// Hover
&.hover {
transform: translate(-$distanceHover, -1%) rotate(-$angleHover) scale($scale);
}
}
// Next photo
&.is-next {
z-index: 8;
transform: translate(40%, 0) scale(0.85);
@include breakpoint (sm) {
z-index: 9;
transform: translate($distance, -1%) rotate($angle) scale($scale);
}
// Hover
&.hover {
transform: translate($distanceHover, -1%) rotate($angleHover) scale($scale);
}
}
}
// Picture
&__picture {
display: block; display: block;
overflow: hidden;
width: 100%; width: 100%;
height: auto; height: 100%;
box-shadow: 0 pxVW(15) pxVW(60) rgba(#000, 0.3);
@include breakpoint (sm) {
border-radius: $radius;
} }
// Overlay // Overlay
@@ -91,62 +152,13 @@
background-color: $color-primary; background-color: $color-primary;
} }
// Active photo
&--active {
opacity: 1;
z-index: 10;
transform: scale(1);
img { img {
opacity: 1; opacity: 0;
} position: relative;
} z-index: 1;
display: block;
// Previous & next photo width: 100%;
&--prev, &--next { height: auto;
opacity: 1;
img {
opacity: 1;
}
&:before {
@include breakpoint (sm) {
opacity: 0.4;
}
}
}
// Previous photo
&--prev {
z-index: 9;
transform: translate(-40%, 0) scale(0.85);
@include breakpoint (sm) {
z-index: 8;
transform: translate(-$distance, -1%) rotate(-$angle) scale($scale);
}
// Hover
&.hover {
transform: translate(-$distanceHover, -1%) rotate(-$angleHover) scale($scale);
}
}
// Next photo
&--next {
z-index: 8;
transform: translate(40%, 0) scale(0.85);
@include breakpoint (sm) {
z-index: 9;
transform: translate($distance, -1%) rotate($angle) scale($scale);
}
// Hover
&.hover {
transform: translate($distanceHover, -1%) rotate($angleHover) scale($scale);
}
} }
} }
} }
@@ -193,7 +205,7 @@
/* /*
** Information ** Informations
*/ */
&__infos { &__infos {
position: relative; position: relative;
@@ -232,14 +244,14 @@
} }
// States // States
&--prev { &.is-prev {
transform: translateY(-$distance); transform: translateY(-$distance);
} }
&--active { &.is-active {
transform: translateY(0); transform: translateY(0);
opacity: 1; opacity: 1;
} }
&--next { &.is-next {
transform: translateY($distance); transform: translateY($distance);
} }
@@ -312,44 +324,3 @@
} }
} }
} }
/*
** Zoomer
*/
.zoomer {
opacity: 0;
pointer-events: none;
position: absolute;
z-index: 101;
top: 0;
right: 0;
left: 0;
bottom: 0;
&.show {
opacity: 1;
pointer-events: auto;
}
// Image
&__image {
width: 100%;
height: 100%;
overflow: auto;
img {
display: block;
height: 100%;
width: auto;
}
}
// Button
.button-control {
position: absolute;
bottom: 32px;
left: 50%;
transform: translateX(-50%);
}
}

View File

@@ -38,6 +38,7 @@
@include breakpoint (sm) { @include breakpoint (sm) {
display: flex; display: flex;
align-items: center; align-items: center;
padding-top: 6px;
} }
li { li {
@@ -49,6 +50,7 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
margin-bottom: 32px; margin-bottom: 32px;
margin-top: 3px;
@include breakpoint (sm) { @include breakpoint (sm) {
margin-bottom: 0; margin-bottom: 0;
@@ -56,7 +58,7 @@
} }
li { li {
margin: 3px 20px 0; margin-right: 20px;
} }
a { a {
display: block; display: block;

View File

@@ -1,6 +1,7 @@
.browse { .browse {
margin-top: 72px; margin-top: 72px;
margin-bottom: 72px; margin-bottom: 72px;
overflow-x: hidden;
@include breakpoint (sm) { @include breakpoint (sm) {
margin-top: 120px; margin-top: 120px;

View File

@@ -50,13 +50,11 @@
} }
// Photos // Photos
.gallery__photo { .gallery__picture:before {
&:before {
background-color: $color-secondary; background-color: $color-secondary;
} }
} }
} }
}
// Explore // Explore

View File

@@ -37,6 +37,7 @@
@import "organisms/footer"; @import "organisms/footer";
// Layouts // Layouts
@import "layouts/main";
@import "layouts/explore"; @import "layouts/explore";
// Pages // Pages

View File

@@ -23,5 +23,7 @@
</script> </script>
<svelte:head> <svelte:head>
{#if process.env.NODE_ENV !== 'development'}
<script async src="https://www.googletagmanager.com/gtag/js?id={id}"></script> <script async src="https://www.googletagmanager.com/gtag/js?id={id}"></script>
{/if}
</svelte:head> </svelte:head>

View File

@@ -1,6 +1,12 @@
<script> <script>
import { stores } from '@sapper/app' import { stores } from '@sapper/app'
import { pageReady, animDurationLong, pageTransition } from './store' import {
pageReady,
pageTransition,
transitionLong,
transitionPanelIn,
transitionDelay
} from './store'
const { page } = stores() const { page } = stores()
// Components // Components
@@ -11,6 +17,9 @@
import { animateIn, animateOut } from 'animations/Transition' import { animateIn, animateOut } from 'animations/Transition'
// Check if path is excluded
const isExcluded = path => path.includes(['/viewer/'])
/* /*
** PAGE LOADING PROCESS ** PAGE LOADING PROCESS
** 1. Set pageReady to false ** 1. Set pageReady to false
@@ -24,21 +33,16 @@
let firstLoad = true let firstLoad = true
let previousPage = '' let previousPage = ''
// Check if viewer
const isExcluded = path => path.includes(['/viewer/'])
// 1. Watch page change // 1. Watch page change
page.subscribe(page => { page.subscribe(page => {
// Run transition if page is not excluded // Run transition if page is not excluded
if (!isExcluded(previousPage) || !isExcluded(page.path)) { if (!isExcluded(previousPage) || !isExcluded(page.path)) {
// Run the loader animation (only after first load) // Run the loader animation (first load only)
if (!firstLoad) { if (!firstLoad) {
animateIn(scope) animateIn(scope)
} }
// TODO: Figure out how to delay the page rendering a little bit before the end of the transition panel ending // Reset pageReady when changing page
// Set pageReady to false (?)
pageReady.set(false) pageReady.set(false)
} }
@@ -49,19 +53,13 @@
// 2. Watch when loaded changes // 2. Watch when loaded changes
pageReady.subscribe(loaded => { pageReady.subscribe(loaded => {
if (loaded) { if (loaded) {
// 3. Hide the loader // 3. Hide the loader and set firstLoad to false (in order to show the second icon afterwards)
setTimeout(() => {
// Also sets firstLoad to false in order to show the second icon afterwards
animateOut(scope, () => firstLoad = false) animateOut(scope, () => firstLoad = false)
}, 400) // This duration allows to not come over the transition In
// [OU ALORS] les pages changent la valeur de loaded plus tard
// Scroll back to top of page // Scroll back to top of page
setTimeout(() => { setTimeout(() => window.scrollTo(0,0), transitionDelay)
window.scrollTo(0,0)
}, animDurationLong * 0.75 + 400)
// 4. Run the page's transition in, but a little bit before the end of the loader // 4. Run page entering animation
pageTransition.onAnimationEnd() pageTransition.onAnimationEnd()
} }
}) })
@@ -70,7 +68,7 @@
<div class="transition" id="transition" aria-hidden="true" bind:this={scope}> <div class="transition" id="transition" aria-hidden="true" bind:this={scope}>
<div class="transition__loader"> <div class="transition__loader">
{#if firstLoad} {#if firstLoad}
<TitleSite /> <TitleSite init="true" />
{:else} {:else}
<IconGlobe width="44" color="#fff" animated="true" /> <IconGlobe width="44" color="#fff" animated="true" />

View File

@@ -163,6 +163,7 @@ export const relativeTime = (originDate, limit = 0) => {
** Controls Anime.js parallax ** Controls Anime.js parallax
*/ */
export const parallaxAnime = (element, anime) => { export const parallaxAnime = (element, anime) => {
if (element) {
const bound = element.getBoundingClientRect() const bound = element.getBoundingClientRect()
const windowHeight = window.innerHeight const windowHeight = window.innerHeight
if (bound.top < windowHeight && bound.bottom > 0) { if (bound.top < windowHeight && bound.bottom > 0) {
@@ -175,6 +176,7 @@ export const parallaxAnime = (element, anime) => {
} }
} }
} }
}
/* /*

View File

@@ -35,5 +35,7 @@ export let fullscreen = writable()
/* ========================================================================== /* ==========================================================================
Animation related Animation related
========================================================================== */ ========================================================================== */
export const animDuration = 1400 export const transitionDelay = 1400
export const animDurationLong = 1800 export const transitionNormal = 1400
export const transitionLong = 1800
export const transitionPanelIn = 700

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 B

After

Width:  |  Height:  |  Size: 519 B

View File

@@ -1,3 +0,0 @@
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
<path d="M11.245 0c1.615.005 2.002.02 2.878.06 1.064.048 1.791.217 2.427.464a4.902 4.902 0 0 1 1.772 1.154 4.902 4.902 0 0 1 1.153 1.771c.247.636.416 1.363.465 2.428.042.914.056 1.295.06 3.095v2.055c-.004 1.8-.018 2.182-.06 3.096-.049 1.064-.218 1.791-.465 2.427a4.902 4.902 0 0 1-1.153 1.772 4.902 4.902 0 0 1-1.772 1.153c-.636.247-1.363.416-2.427.465-1.067.049-1.407.06-4.123.06s-3.057-.011-4.124-.06c-1.064-.049-1.79-.218-2.427-.465a4.902 4.902 0 0 1-1.771-1.153A4.902 4.902 0 0 1 .524 16.55c-.247-.636-.416-1.363-.465-2.427C.02 13.247.005 12.86 0 11.245v-2.49c.005-1.616.02-2.002.06-2.878.048-1.065.217-1.792.464-2.428a4.902 4.902 0 0 1 1.154-1.771A4.902 4.902 0 0 1 3.448.524C4.086.277 4.813.108 5.877.06 6.753.02 7.14.005 8.754 0zm-.204 1.802H8.958c-1.739.003-2.101.016-3 .057-.974.045-1.504.208-1.856.345-.467.181-.8.398-1.15.748-.35.35-.567.683-.748 1.15-.137.352-.3.882-.345 1.857-.04.898-.054 1.26-.057 2.999v2.083c.003 1.739.016 2.101.057 3 .045.975.208 1.504.345 1.857.181.466.398.8.748 1.15.35.35.683.566 1.15.747.352.137.882.3 1.857.345 1.054.048 1.37.058 4.04.058h.288c2.407 0 2.738-.012 3.754-.058.975-.045 1.504-.208 1.857-.345.466-.18.8-.398 1.15-.748.35-.35.566-.683.747-1.15.137-.352.3-.881.345-1.856.048-1.055.058-1.371.058-4.041v-.288c0-2.407-.012-2.738-.058-3.753-.045-.975-.208-1.505-.345-1.857a3.098 3.098 0 0 0-.748-1.15 3.099 3.099 0 0 0-1.15-.748c-.352-.137-.881-.3-1.856-.345-.899-.04-1.261-.054-3-.057zM10 4.864a5.135 5.135 0 1 1 0 10.271 5.135 5.135 0 0 1 0-10.27zm0 1.802a3.334 3.334 0 1 0 0 6.667 3.334 3.334 0 0 0 0-6.667zm5.338-3.205a1.2 1.2 0 1 1 0 2.4 1.2 1.2 0 0 1 0-2.4z" fill="#FFF" fill-rule="evenodd"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1020 B

After

Width:  |  Height:  |  Size: 368 B