From 14e5430a9d784fcf10fb8275afb481feeca5a90f Mon Sep 17 00:00:00 2001 From: Curtis Dulmage Date: Fri, 26 Jul 2024 13:23:53 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=84=20[PWA]=20Improve=20overall=20page?= =?UTF-8?q?=20loading=20and=20caching=20(#61)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :recycle: [OpenGraph] Add some additional twitter tags * :bug: [Cursors] Bring back preloading * :dizzy: [Page] Improve page loading * :hammer_and_wrench: [PWA] Revise config --- astro.config.mjs | 6 ++- src/components/ContentBlock.astro | 6 +++ src/layouts/Page.astro | 46 ++++++++++++++++------ src/pages/404.astro | 12 ++++-- src/pages/index.astro | 4 +- src/scripts/PageLoad.ts | 40 +++++++++++++++++++ src/sections/Intro.astro | 15 +++++--- src/styles/global.css | 64 +++++++++++++++++-------------- 8 files changed, 142 insertions(+), 51 deletions(-) create mode 100644 src/scripts/PageLoad.ts diff --git a/astro.config.mjs b/astro.config.mjs index b04f6fe..5135dc1 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -34,9 +34,11 @@ export default defineConfig({ AstroPWA({ workbox: { // Not sure how this differs from `includeAssets`... - // globPatterns: ['**/*.{js,css,html,ico,png,svg}'], + globPatterns: ['**/*.{css,js,html,woff2}', 'assets/*.{png,webp}'], // Not sure if we actually want to specify this fallback. - navigateFallback: '/404', + navigateFallback: '/', + // The `chicken` image is 2.2MB, so we increase the limit to 3MB. + maximumFileSizeToCacheInBytes: 3000000, }, // Specify which public assets (in addition to the default html/css/js) diff --git a/src/components/ContentBlock.astro b/src/components/ContentBlock.astro index 61aa29f..3871967 100644 --- a/src/components/ContentBlock.astro +++ b/src/components/ContentBlock.astro @@ -63,6 +63,12 @@ const inactive = !title || !subtitle; /* Just a small nudge for better vertical centering */ padding-top: calc(var(--space-tightest) + 0.1rem); + /* Consider improveing the legibility of text */ + /* + background-color: rgb(255, 255, 255, 0.04); + backdrop-filter: blur(2px); + */ + & > h3 { font-weight: 800; } diff --git a/src/layouts/Page.astro b/src/layouts/Page.astro index d30b4bf..77e59b9 100644 --- a/src/layouts/Page.astro +++ b/src/layouts/Page.astro @@ -27,7 +27,7 @@ const OG_IMAGE = new URL('/dulmage-social.png', Astro.site).href; --- - + + + @@ -129,23 +131,45 @@ const OG_IMAGE = new URL('/dulmage-social.png', Astro.site).href; display: flex; justify-content: center; } + + /* --- Page load --- */ + + @keyframes pageLoadScreenCover { + from { + opacity: 1; + visibility: visible; + } + to { + opacity: 0; + visibility: hidden; + } + } + + body { + position: relative; + + &::after { + content: ''; + z-index: var(--index-mesosphere); + position: fixed; + inset: 0; + pointer-events: none; + background-color: black; + } + } + + html[data-ready='done'] body::after { + animation: pageLoadScreenCover var(--speed-slower) var(--ease) forwards; + } diff --git a/src/pages/404.astro b/src/pages/404.astro index ad74bec..7756be6 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -47,17 +47,23 @@ import Stars from '@components/Stars.astro'; } } - .ErrorContent { + :global(#Main404) { --color-portfolio: hsl(var(--color-rainbow) 100% 50%); + animation: rainbowSpin 4s linear infinite both; + } - position: relative; + .ErrorContent { display: grid; justify-content: center; gap: var(--space-tight); padding: var(--space); text-align: center; max-width: 90rem; - animation: rainbowSpin 4s linear infinite both; + + /* Page load (fade-in) */ + position: relative; + z-index: var(--index-thermosphere); + animation: fadeIn var(--speed-slower) var(--speed-slow) var(--ease) both; } .ErrorContent h4 a { diff --git a/src/pages/index.astro b/src/pages/index.astro index 42b0d92..b23de78 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -4,6 +4,7 @@ import Page from '@layouts/Page.astro'; import {NAV_ID, NAV_TOGGLE_ID, OVERLAY_ID} from '@data/app'; import {sections} from '@data/sections'; +import Contact from '@components/Contact.astro'; import Hamburger from '@components/Hamburger.astro'; import Navigation from '@components/Navigation.astro'; import Project from '@components/Project.astro'; @@ -14,8 +15,9 @@ import ProjectOverlay from '@sections/ProjectOverlay.astro'; const [intro, ...portfolioSections] = sections; --- - + + diff --git a/src/scripts/PageLoad.ts b/src/scripts/PageLoad.ts new file mode 100644 index 0000000..86cc8fa --- /dev/null +++ b/src/scripts/PageLoad.ts @@ -0,0 +1,40 @@ +export type HtmlReady = 'loading' | 'done' | 'error'; + +export class PageLoad { + static MOTION_DELAY = 1200; + + static documentState() { + return document.readyState; + } + + static isHome() { + const {pathname} = window.location; + return pathname === '' || pathname === '/'; + } + + static isLoaded() { + return document.documentElement.dataset.ready === 'done'; + } + + static schedule() { + if (PageLoad.documentState() === 'complete') { + PageLoad.#updateDocument(); + return; + } + + document.addEventListener('readystatechange', PageLoad.#handleReadyState); + } + + static #handleReadyState() { + window.scrollTo(0, 0); + window.setTimeout(PageLoad.#updateDocument, PageLoad.MOTION_DELAY); + } + + static #updateDocument() { + document.documentElement.dataset.ready = 'done'; + document.removeEventListener( + 'readystatechange', + PageLoad.#handleReadyState, + ); + } +} diff --git a/src/sections/Intro.astro b/src/sections/Intro.astro index 8d4c265..57d2b9f 100644 --- a/src/sections/Intro.astro +++ b/src/sections/Intro.astro @@ -1,6 +1,5 @@ --- import {type SectionEntry} from '@data/types'; -import Contact from '@components/Contact.astro'; interface Props { id: SectionEntry['id']; @@ -24,15 +23,14 @@ const {id, thumbnail} = Astro.props; Background image photographed by: Curtis Dulmage

-

+

Curtis Dulmage. Front end web developer. - Ottawa, Canada. Here are a few of my most recent projects. Please - get in touch if you have any questions. Thank you. + Ottawa, Canada. + Here are a few of my most recent projects. + Please get in touch if you have any questions. Thank you.

- - @@ -52,6 +50,11 @@ const {id, thumbnail} = Astro.props; @media (--min-tablet) { gap: var(--space); } + + /* Page load (fade-in) */ + position: relative; + z-index: var(--index-thermosphere); + animation: fadeIn var(--speed-slower) var(--speed-slow) var(--ease) both; } .Details { diff --git a/src/styles/global.css b/src/styles/global.css index c988c20..5c757c7 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -87,34 +87,6 @@ body { cursor: url('../assets/svg/cursors/CursorAuto.svg'), auto; } -/* --- Page load --- */ -/* TODO: Consider something better with `document.readystate`. */ - -@keyframes pageLoad { - from { - opacity: 1; - visibility: visible; - } - to { - opacity: 0; - visibility: hidden; - } -} - -body { - position: relative; - - &::after { - content: ''; - z-index: var(--index-mesosphere); - position: fixed; - inset: 0; - pointer-events: none; - background-color: black; - animation: pageLoad var(--speed-slow) var(--speed) var(--ease) forwards; - } -} - /* --- Smooth scroll + snapping --- */ /* Disabled because it breaks "dynamic chrome" behaviour on iOS */ @@ -305,3 +277,39 @@ button { cursor: url('../assets/svg/cursors/CursorPointerClicked.svg'), pointer; } } + +.preload-cursors { + /* + Required to preload the variant cursor. Otherwise, there will be + a delay upon click when switching to the different cursor asset. + */ + + > b { + cursor: url('../assets/svg/cursors/CursorDeadClicked.svg'), auto; + } + + > u { + cursor: url('../assets/svg/cursors/CursorHornsClicked.svg'), pointer; + } + + > i { + cursor: url('../assets/svg/cursors/CursorPointerClicked.svg'), pointer; + } + + /* + > strong { + cursor: url('../assets/svg/cursors/CursorGrabClicked.svg'), pointer; + } + */ +} + +/* --- Global animations --- */ + +@keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } +}