From be0f4c8b59c089df37f6235fd8bdf218478fdfcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fe=CC=81lix=20Pe=CC=81ault?= Date: Thu, 9 Apr 2020 20:23:24 +0200 Subject: [PATCH] Optimize animations and transitions will-change is apparently not enough to run GPU-enabled animations, use translateZ on top of it --- package.json | 2 +- pnpm-lock.yaml | 8 ++++---- src/animations/Carousel.js | 6 +++++- src/animations/Locations.js | 7 +++++-- src/animations/Photo.js | 6 ++++-- src/animations/TitleSite.js | 1 + src/animations/index.js | 10 ++++++++-- src/animations/page.js | 15 ++++++++++++-- src/animations/place.js | 9 ++++++--- src/animations/viewer.js | 6 ++++-- src/atoms/Counter.svelte | 2 +- src/organisms/Pagination.svelte | 2 +- src/style/molecules/_location.scss | 2 +- src/style/organisms/_carousel.scss | 30 ++++++++++++++-------------- src/style/organisms/_fullscreen.scss | 8 ++++---- src/style/organisms/_pagination.scss | 4 ++-- 16 files changed, 75 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index 1ec1cc6..cea2de9 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "serve": "node server/server.js" }, "dependencies": { - "animejs": "^3.1.0", + "animejs": "^3.2.0", "compression": "^1.7.4", "imagesloaded": "^4.1.4", "lazysizes": "^5.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6a94f2..f805c27 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,5 @@ dependencies: - animejs: 3.1.0 + animejs: 3.2.0 compression: 1.7.4 imagesloaded: 4.1.4 lazysizes: 5.2.0 @@ -1043,10 +1043,10 @@ packages: node: '>=0.4.2' resolution: integrity: sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= - /animejs/3.1.0: + /animejs/3.2.0: dev: false resolution: - integrity: sha512-BjnCroPPQPEAngT0M89pz9TBcOGgOFLnVoq3+jV2upl4rn60k57/AXvESTnuILsNgOEjGuhMEOMp7IlQzk40kA== + integrity: sha512-zhtGl5cS0G2f5DfciMO8uwWpnx06nfFnHlXYYXHBazHep1Lyd6kEtBQP+9hpYKE0dBZjIigHp9VpMO95ZfXQJQ== /ansi-escapes/4.3.1: dependencies: type-fest: 0.11.0 @@ -4872,7 +4872,7 @@ specifiers: '@rollup/plugin-commonjs': ^11.0.2 '@rollup/plugin-node-resolve': ^7.1.1 '@rollup/plugin-replace': ^2.3.1 - animejs: ^3.1.0 + animejs: ^3.2.0 autoprefixer: ^9.7.6 babel-plugin-module-resolver: ^4.0.0 compression: ^1.7.4 diff --git a/src/animations/Carousel.js b/src/animations/Carousel.js index 2b0823b..8d3792a 100644 --- a/src/animations/Carousel.js +++ b/src/animations/Carousel.js @@ -18,6 +18,7 @@ export const animateIn = scope => { tl.add({ targets: scope, translateY: [32, 0], + translateZ: [0, 0], opacity: [0, 1], complete: event => event.animatables[0].target.removeAttribute('style') }) @@ -25,7 +26,8 @@ export const animateIn = scope => { // Photo: Active tl.add({ targets: scope.querySelector('.is-active picture'), - translateY: [8, 0] + translateY: [8, 0], + translateZ: [0, 0] }, 100) // Photo: Prev @@ -33,6 +35,7 @@ export const animateIn = scope => { targets: scope.querySelector('.is-prev picture'), translateY: [8, 0], translateX: [64, 0], + translateZ: [0, 0], rotate: window.innerWidth >= 768 ? [-2, 0] : [0, 0] }, 100) @@ -41,6 +44,7 @@ export const animateIn = scope => { targets: scope.querySelector('.is-next picture'), translateY: [8, 0], translateX: [-48, 0], + translateZ: [0, 0], rotate: window.innerWidth >= 768 ? [2, 0] : [0, 0] }, 100) diff --git a/src/animations/Locations.js b/src/animations/Locations.js index 633ae31..7a9a214 100644 --- a/src/animations/Locations.js +++ b/src/animations/Locations.js @@ -24,19 +24,22 @@ export const animateIn = scope => { targets: location.querySelector('img'), scale: [1.3, 1], opacity: [0, 1], + translateZ: [0, 0], duration: 1800 }, 100) // Name tl.add({ targets: location.querySelector('h3'), - translateY: ['100%', 0] + translateY: ['100%', 0], + translateZ: [0, 0], }, 150) // Country tl.add({ targets: location.querySelector('p'), - translateY: ['100%', 0] + translateY: ['100%', 0], + translateZ: [0, 0] }, 200) // Scroll reveal diff --git a/src/animations/Photo.js b/src/animations/Photo.js index 6fa9893..87c4dda 100644 --- a/src/animations/Photo.js +++ b/src/animations/Photo.js @@ -18,6 +18,7 @@ export const animateIn = scope => { tlLocation.add({ targets: scope.querySelectorAll('.photo__location .line span'), translateY: ['100%', 0], + translateZ: [0, 0], delay: anime.stagger(120) }, 200) // Description @@ -48,7 +49,8 @@ export const animateIn = scope => { }, 50) photoReveal.add({ targets: scope.querySelector('.photo__picture img'), - scale: [1.12, 1] + scale: [1.12, 1], + translateZ: [0, 0] }, 50) // Show photo when image is loaded @@ -67,8 +69,8 @@ export const animateIn = scope => { const numberPallax = anime({ targets: number.querySelector('span'), translateY: (window.innerWidth <= 768) ? ['0%', '20%'] : ['-20%', '20%'], - duration: 2000, easing: 'linear', + duration: 2000, autoplay: false }) const numberPallaxAnime = () => parallaxAnime(number, numberPallax) diff --git a/src/animations/TitleSite.js b/src/animations/TitleSite.js index ee5424f..2d75a9e 100644 --- a/src/animations/TitleSite.js +++ b/src/animations/TitleSite.js @@ -11,6 +11,7 @@ export const animateIn = (scope, init) => { const letters = anime({ targets: scope.querySelectorAll('span, em span'), translateY: ['100%', 0], + translateZ: [0, 0], easing: 'easeOutQuart', duration: 1000, delay: anime.stagger(40, { start: init ? 0 : animDelay }), diff --git a/src/animations/index.js b/src/animations/index.js index 8ad292e..1ccea1d 100644 --- a/src/animations/index.js +++ b/src/animations/index.js @@ -12,15 +12,17 @@ export const animateIn = () => { const titleHouses = anime({ targets: document.querySelectorAll('#title-houses span'), translateY: ['-70%', 0], + translateZ: [0, 0], + easing: 'easeOutQuart', delay: anime.stagger(80, { start: animDelay }), - duration: animDuration, - easing: 'easeOutQuart' + duration: animDuration }) // Parallax on scroll const translate = anime({ targets: '#title-houses', translateX: ['7%', '-15%'], + translateZ: [0, 0], easing: 'linear', duration: animDuration, autoplay: false @@ -33,6 +35,7 @@ export const animateIn = () => { targets: document.getElementById('intro-description').querySelectorAll('p, a'), opacity: [0, 1], translateY: [8, 0], + translateZ: [0, 0], easing: 'easeOutQuart', duration: animDuration, delay: anime.stagger(200, { start: animDelay + 200 }) @@ -43,6 +46,7 @@ export const animateIn = () => { const titleOfReveal = anime({ targets: titleOf.querySelectorAll('span'), translateY: ['100%', 0], + translateZ: [0, 0], easing: 'easeOutQuart', delay: anime.stagger(70), duration: animDuration, @@ -59,6 +63,7 @@ export const animateIn = () => { const titleWorldReveal = anime({ targets: titleWorld.querySelectorAll('span'), translateY: ['100%', 0], + translateZ: [0, 0], easing: 'easeOutQuart', delay: anime.stagger(70), duration: animDuration, @@ -67,6 +72,7 @@ export const animateIn = () => { const titleWorldParallax = anime({ targets: titleWorld, translateX: ['5%', '-3%'], + translateZ: [0, 0], easing: 'linear', duration: animDuration, autoplay: false diff --git a/src/animations/page.js b/src/animations/page.js index 33b622c..214e09c 100644 --- a/src/animations/page.js +++ b/src/animations/page.js @@ -8,13 +8,24 @@ import { animDuration, animDelay } from 'utils/store' export const animateIn = () => { const tl = anime.timeline({ easing: 'easeOutQuart', - duration: animDuration + duration: animDuration, + delay: animDelay }) + // Simple slide and fade on each part of the page tl.add({ targets: document.querySelectorAll('.page__part'), opacity: [0, 1], translateY: [8, 0], - delay: anime.stagger(160, { start: animDelay }) + translateZ: [0, 0], + delay: anime.stagger(160) }) + + // Globe + tl.add({ + targets: document.querySelector('.globe'), + opacity: [0, 1], + translateY: ['5%', 0], + translateZ: [0, 0] + }, 200) } diff --git a/src/animations/place.js b/src/animations/place.js index 75b01ad..c4447dc 100644 --- a/src/animations/place.js +++ b/src/animations/place.js @@ -15,7 +15,8 @@ export const animateIn = () => { // Title: Houses tl.add({ targets: '.place__title_houses', - translateY: ['150%', 0] + translateY: ['150%', 0], + translateZ: [0, 0] }) // Title: Of tl.add({ @@ -25,7 +26,8 @@ export const animateIn = () => { // Title: Place name tl.add({ targets: '.place__title_name', - translateY: ['150%', 0] + translateY: ['150%', 0], + translateZ: [0, 0] }, 150) // Switcher link @@ -46,6 +48,7 @@ export const animateIn = () => { tl.add({ targets: '.place__description', opacity: [0, 1], - translateY: [24, 0] + translateY: [24, 0], + translateZ: [0, 0] }, 450) } diff --git a/src/animations/viewer.js b/src/animations/viewer.js index 7955e4e..3df09d6 100644 --- a/src/animations/viewer.js +++ b/src/animations/viewer.js @@ -17,7 +17,8 @@ export const animateIn = () => { tl.add({ targets: viewer.querySelector('.carousel .wrap'), opacity: [0, 1], - translateY: ['-4%', 0] + translateY: ['-4%', 0], + translateZ: [0, 0] }) // Carousel: Number @@ -31,6 +32,7 @@ export const animateIn = () => { tl.add({ targets: viewer.querySelectorAll('.carousel__dots'), translateY: [16, 0], + translateZ: [0, 0], opacity: [0, 1] }, 150) @@ -38,8 +40,8 @@ export const animateIn = () => { tl.add({ targets: viewer.querySelectorAll('.tip, .viewer__buttons a'), translateY: [-32, 0], + translateZ: [0, 0], opacity: [0, 1], delay: anime.stagger(120), }, 400) - } diff --git a/src/atoms/Counter.svelte b/src/atoms/Counter.svelte index 4917769..ce47846 100644 --- a/src/atoms/Counter.svelte +++ b/src/atoms/Counter.svelte @@ -38,7 +38,7 @@
{#each digits as digit} -
+
{#each numbers as number} {number} {/each} diff --git a/src/organisms/Pagination.svelte b/src/organisms/Pagination.svelte index d19f1ec..e7344fd 100644 --- a/src/organisms/Pagination.svelte +++ b/src/organisms/Pagination.svelte @@ -45,7 +45,7 @@ >
page
-
+
{#each pagesArray as page} {page} {/each} diff --git a/src/style/molecules/_location.scss b/src/style/molecules/_location.scss index 558c808..cd26a69 100644 --- a/src/style/molecules/_location.scss +++ b/src/style/molecules/_location.scss @@ -65,7 +65,7 @@ &:after { opacity: 1; - transform: translate(-50%, -50%) scale(1); + transform: scale(1) translate(-50%, -50%); } } diff --git a/src/style/organisms/_carousel.scss b/src/style/organisms/_carousel.scss index 1a1318b..fe6cf0d 100644 --- a/src/style/organisms/_carousel.scss +++ b/src/style/organisms/_carousel.scss @@ -63,7 +63,8 @@ left: 0; width: 100%; height: 100%; - transform: scale($scale); + box-shadow: 0 pxVW(15) pxVW(60) rgba(#000, 0.3); + transform: scale($scale) translateZ(0); transition: transform $duration $ease-quart, opacity ($duration / 2) $ease-quart; pointer-events: none; @extend %willchange; @@ -72,7 +73,7 @@ &.is-active { opacity: 1; z-index: 10; - transform: scale(1); + transform: scale(1) translateZ(0); pointer-events: auto; img { @@ -99,32 +100,32 @@ // Previous photo &.is-prev { z-index: 9; - transform: translate(-40%, 0) scale(0.85); + transform: translate(-40%, 0) scale(0.85) translateZ(0); @include breakpoint (sm) { z-index: 8; - transform: translate(-$distance, -1%) rotate(-$angle) scale($scale); + transform: translate(-$distance, -1%) rotate(-$angle) scale($scale) translateZ(0); } // Hover &.hover { - transform: translate(-$distanceHover, -1%) rotate(-$angleHover) scale($scale); + transform: translate(-$distanceHover, -1%) rotate(-$angleHover) scale($scale) translateZ(0); } } // Next photo &.is-next { z-index: 8; - transform: translate(40%, 0) scale(0.85); + transform: translate(40%, 0) scale(0.85) translateZ(0); @include breakpoint (sm) { z-index: 9; - transform: translate($distance, -1%) rotate($angle) scale($scale); + transform: translate($distance, -1%) rotate($angle) scale($scale) translateZ(0); } // Hover &.hover { - transform: translate($distanceHover, -1%) rotate($angleHover) scale($scale); + transform: translate($distanceHover, -1%) rotate($angleHover) scale($scale) translateZ(0); } } } @@ -136,7 +137,6 @@ overflow: hidden; width: 100%; height: 100%; - box-shadow: 0 pxVW(15) pxVW(60) rgba(#000, 0.3); @extend %willchange; @include breakpoint (sm) { @@ -271,15 +271,15 @@ // States &.is-prev { - transform: translateY(-$distance); + transform: translateY(-$distance) translateZ(0); } &.is-active { - transform: translateY(0); + transform: translateY(0) translateZ(0); opacity: 1; pointer-events: auto; } &.is-next { - transform: translateY($distance); + transform: translateY($distance) translateZ(0); } } @@ -311,18 +311,18 @@ // Active &.active button { background-color: $color-secondary; - transform: scale(1.25); + transform: scale(1.25) translateZ(0); } // Small dot &.small button { - transform: scale(0.6); + transform: scale(0.6) translateZ(0); opacity: 0.5; } // Hidden &.hidden { padding: 0; - transform: scale(0); + transform: scale(0) translateZ(0); opacity: 0; width: 0; height: 0; diff --git a/src/style/organisms/_fullscreen.scss b/src/style/organisms/_fullscreen.scss index 8d105b6..140616d 100644 --- a/src/style/organisms/_fullscreen.scss +++ b/src/style/organisms/_fullscreen.scss @@ -49,13 +49,13 @@ display: flex; justify-content: center; opacity: 0; - transform: scale(1.1) translateY(24px); + transform: scale(1.1) translateY(24px) translateZ(0); transition: transform 0.8s $ease-quart, opacity 0.8s $ease-quart; // Visible state &.is-visible { opacity: 1; - transform: scale(1) translateY(0); + transform: scale(1) translateY(0) translateZ(0); } } @@ -66,7 +66,7 @@ top: 50%; left: 50%; opacity: 1; - transform: translate(-50%, -50%); + transform: translate(-50%, -50%) translateZ(0); transform-origin: 50% 50%; display: flex; align-items: center; @@ -79,7 +79,7 @@ // Hidden state &.is-hidden { - transform: scale(1.05) translate(-50%, -50%); + transform: scale(1.05) translate(-50%, -50%) translateZ(0); opacity: 0; } } diff --git a/src/style/organisms/_pagination.scss b/src/style/organisms/_pagination.scss index 3aebfc6..21e2d24 100644 --- a/src/style/organisms/_pagination.scss +++ b/src/style/organisms/_pagination.scss @@ -57,7 +57,7 @@ .scroll { display: flex; flex-direction: column; - transform: translate(0, 0); + transform: translate(0, 0) translateZ(0); text-align: right; line-height: 0.85; transition: transform 325ms $ease-cubic; @@ -70,7 +70,7 @@ position: absolute; top: 50%; left: 50%; - transform: translate(-50%, -72%); + transform: translate(-50%, -72%) translateZ(0); font-family: $font-serif; font-size: rem(18px); color: $color-secondary-bright;