Refacto JS parallax

This commit is contained in:
DrMint 2024-06-01 11:48:48 +02:00
parent f6c704f6d1
commit 43d5d1568b
6 changed files with 33 additions and 137 deletions

View File

@ -132,6 +132,9 @@ A parallax effect is applied on the webpages' background image. This effect can
## CSS Utility classes ## CSS Utility classes
- `.dark-theme`: force dark theming to the element and its children.
- `.light-theme`: force light theming to the element and its children.
- `when-js`: only display element if JavaScript is available - `when-js`: only display element if JavaScript is available
- `when-no-js`: only display element if JavaScript is unavailable - `when-no-js`: only display element if JavaScript is unavailable
@ -140,21 +143,28 @@ A parallax effect is applied on the webpages' background image. This effect can
- `when-no-print`: only display when not printing - `when-no-print`: only display when not printing
- `font-serif`: by default, everything use sans-serif. Use this class to make the font serif.
- `font-[size]`: apply size from font size system. Valid sizes are `xs`, `s`, `m`, `l`, `xl`, `2xl`, `3xl`, `4xl`, and `5xl`
- `hide-scrollbar`: hide the element scrollbar - `hide-scrollbar`: hide the element scrollbar
- `texture-dots`: add a background paper like texture to the element - `texture-dots`: add a background paper like texture to the element
- `font-serif`: by default, everything use sans-serif. Use this class to make the font serif.
- `high-contrast-text`: add a shadow around the text to increase perceived contrast. - `high-contrast-text`: add a shadow around the text to increase perceived contrast.
- `prose`: apply typography rules. Useful for main text content - `prose`: apply typography rules. Useful for main text content
- `error-message`: make the element flash with a red background.
- `DEV_TODO`: completely hide the element. Useful if some element should remain in the codebase but shouldn't be visible on the page, such as WIP feature.
## CSS Component classes ## CSS Component classes
- `pressable-icon`: used to make a SVG/Text look pressable - `pressable-icon`: used to make a SVG/Text look pressable
- `pressable-link`: used to make links look pressable (text with underline)
- `pressable`: used to make a container look pressable - `pressable`: used to make a container look pressable
## CSS Global Variables ## CSS Global Variables
- `--color-base-X`: the current theme colors. X can be between 0 and 1000, available in increments of 50. - `--color-base-X`: the current theme colors. X can be between 0 and 1000, available in increments of 50.
- `--scroll-relative`: the current vertical scroll position. The value is between 0 (at the top of the page) to 1 (at the bottom of the page)
- `--scroll-absolute`: the current vertical scroll position in px.
- `--font-size-[size]`: apply size from font size system. Valid sizes are `xs`, `s`, `m`, `l`, `xl`, `2xl`, `3xl`, `4xl`, and `5xl`
## Translations ## Translations

View File

@ -6,7 +6,6 @@ import type {
} from "src/shared/payload/payload-sdk"; } from "src/shared/payload/payload-sdk";
import { getRandomId } from "src/utils/random"; import { getRandomId } from "src/utils/random";
import { sizesToSrcset } from "src/utils/img"; import { sizesToSrcset } from "src/utils/img";
import { UAParser } from "ua-parser-js";
interface Props { interface Props {
img: EndpointImage | EndpointMediaThumbnail | EndpointScanImage; img: EndpointImage | EndpointMediaThumbnail | EndpointScanImage;
@ -24,11 +23,6 @@ const style = `
mask-image: linear-gradient( to bottom, rgba(0 0 0 / 30%) 0%, transparent 100% ); mask-image: linear-gradient( to bottom, rgba(0 0 0 / 30%) 0%, transparent 100% );
} }
}`; // Required to be done like this because we can't insert variables in media queries with Astro. }`; // Required to be done like this because we can't insert variables in media queries with Astro.
const userAgent = Astro.request.headers.get("user-agent") ?? "";
const parser = new UAParser(userAgent);
const isParallaxEnabled =
parser.getDevice().type !== "mobile" && parser.getDevice().type !== "tablet";
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
@ -89,19 +83,19 @@ const isParallaxEnabled =
user-select: none; user-select: none;
animation: fadeIn 3s forwards; animation: fadeIn 3s forwards;
@media (min-width: 650.5px) {
transform: translateY(calc(var(--scroll-absolute) * 0.4px));
}
} }
</style> </style>
{/* ------------------------------------------- JS --------------------------------------------- */} {/* ------------------------------------------- JS --------------------------------------------- */}
<script define:vars={{ uniqueId, isParallaxEnabled }} is:inline> <script define:vars={{ uniqueId }} is:inline>
const element = document.getElementById(uniqueId); const element = document.getElementById(uniqueId);
element.style.animationPlayState = "paused"; element.style.animationPlayState = "paused";
if (isParallaxEnabled) {
window.backgroundParralaxElement = element;
}
element.addEventListener( element.addEventListener(
"load", "load",
() => { () => {
@ -110,15 +104,3 @@ const isParallaxEnabled =
{ once: true, passive: true } { once: true, passive: true }
); );
</script> </script>
<script>
const refreshParallax = () => {
if (!("backgroundParralaxElement" in window)) return;
if (!(window.backgroundParralaxElement instanceof HTMLElement)) return;
const parallaxAmount = window.scrollY * 0.4;
window.backgroundParralaxElement.style.transform = `translateY(${parallaxAmount}px)`;
};
document.addEventListener("scroll", refreshParallax, { passive: true });
</script>

View File

@ -758,3 +758,17 @@ const { currentTheme } = Astro.locals;
}); });
}); });
</script> </script>
<script is:inline>
window.addEventListener(
"scroll",
() => {
document.body.style.setProperty(
"--scroll-relative",
window.scrollY / (document.documentElement.offsetHeight - window.innerHeight)
);
document.body.style.setProperty("--scroll-absolute", window.scrollY);
},
false
);
</script>

View File

@ -32,6 +32,8 @@ const { title } = getLocalizedMatch(value.translations);
<OpenMediaPageButton url={getLocalizedUrl(`/audios/${value.id}`)} /> <OpenMediaPageButton url={getLocalizedUrl(`/audios/${value.id}`)} />
</div> </div>
{/* ------------------------------------------- CSS -------------------------------------------- */}
<style> <style>
div { div {
margin-block: 4em; margin-block: 4em;

View File

@ -1,111 +0,0 @@
<!doctype html>
<html>
<body>
<div class="parallax">
<img src="https://dashboard.accords-library.com/images/home-background-image.webp" alt="" />
</div>
<div class="content-outer">
<div class="content-inner">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sed risus in dui porta
elementum. Sed vehicula ante dignissim lacinia egestas. Integer eget massa tellus. Nunc
blandit neque enim, non faucibus nisl dignissim aliquam. Vestibulum et ipsum eget tellus
venenatis bibendum a at arcu. Quisque congue faucibus nisl, sed tristique eros suscipit
nec. Donec quis tincidunt urna. Sed urna dui, placerat aliquet pulvinar vitae, blandit sed
lorem. Curabitur et venenatis nibh, id feugiat nulla. Suspendisse ac mi diam. Nulla vitae
odio metus. Praesent id sagittis dolor, non efficitur ligula.
</p>
<p>
Fusce suscipit eget felis nec euismod. Maecenas odio lacus, aliquam sit amet libero eget,
posuere dignissim odio. Nunc porta elementum massa, nec facilisis tortor sodales in. Nulla
lacus felis, elementum ac urna a, fringilla ultrices ipsum. Pellentesque dapibus congue
fermentum. Praesent tempus risus eget augue viverra, sed tincidunt lacus posuere. Proin
rhoncus nisi libero, vel ultrices ipsum egestas lobortis. Fusce scelerisque accumsan nisi.
Quisque eget felis auctor, pulvinar elit vel, congue enim. Phasellus tincidunt felis
velit, in mollis purus tincidunt sed. Vestibulum scelerisque ipsum ac pellentesque
sagittis. Nam rutrum orci vitae enim volutpat consequat non id augue. Maecenas purus mi,
volutpat sit amet elit id, dapibus pellentesque arcu.
</p>
<p>
Etiam et bibendum tellus. Aliquam at tristique sapien. Mauris lacinia odio erat, et
gravida diam luctus convallis. Phasellus eget velit et arcu placerat lobortis. Curabitur
eleifend id elit quis lobortis. Praesent finibus sapien interdum, ultrices est eget,
faucibus erat. Aliquam neque nibh, fringilla laoreet auctor vestibulum, vestibulum quis
nisl.
</p>
<p>
Sed non metus ut massa pretium faucibus. Nam porta, lorem vel sodales sollicitudin, felis
mi dignissim urna, euismod dapibus ante massa vitae odio. Vivamus porttitor tristique
mauris, vel tempus ligula convallis non. Aliquam finibus dui nec nibh ornare, nec
scelerisque sem molestie. Aenean non leo quis massa scelerisque volutpat vel in dolor.
Curabitur vel massa nec tellus tempus tempor. Pellentesque dignissim ex nec augue viverra
scelerisque. Pellentesque eget tortor euismod, efficitur sem at, maximus ipsum.
</p>
<p>
Pellentesque ipsum sem, pretium non turpis eu, hendrerit eleifend neque. Vestibulum ante
ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Aenean et porta
urna, et lobortis enim. Aliquam erat volutpat. Nunc molestie consequat erat. Donec non
tempus orci. Sed vitae elit lorem. Aliquam erat volutpat.
</p>
</div>
</div>
</body>
</html>
<style>
html {
overflow: hidden;
}
body {
width: 100vw;
height: 100vh;
overflow-x: hidden;
overflow-y: auto;
perspective: 1px;
transform-style: preserve-3d;
}
div.parallax {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
transform-style: preserve-3d;
}
img {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: auto;
max-height: 100%;
object-fit: cover;
object-position: 50% 0;
z-index: -1;
mask-image: linear-gradient(
to bottom,
rgba(0 0 0 / 30%) 0%,
rgba(0 0 0 / 5%) 100vh,
rgba(0 0 0 / 5%) 80%,
transparent 100%
);
user-select: none;
transform: translateZ(-1px) scale(2);
}
</style>

View File

@ -22,7 +22,6 @@ const { icon = "material-symbols:folder-outline", title, href } = Astro.props;
<style> <style>
a { a {
@media (max-width: 600.5px) { @media (max-width: 600.5px) {
flex-grow: 1; flex-grow: 1;
} }