Fix hero
This commit is contained in:
1 parent
755d91d0f4
commit
c8740fb1d3
3 files changed
+229
-4
No files matched your search
@@ -1,6 +1,6 @@
|
||||
---
|
||||
import { Picture } from 'astro:assets';
|
||||
import background from '../../assets/images/background.png';
|
||||
import poster from '../../assets/images/hero-field.png';
|
||||
import { t, type Lang } from '../../i18n/ui';
|
||||
|
||||
interface Props { lang: Lang }
|
||||
@@ -9,9 +9,12 @@ const ui = t(lang);
|
||||
---
|
||||
<section class="hero night" aria-labelledby="hero-title">
|
||||
<div class="hero__media">
|
||||
<!-- Abstract and decorative, so it carries no alt text. -->
|
||||
<!-- Abstract and decorative, so neither layer carries alt text. The poster is a frame of
|
||||
the noise field, so it carries the hero until the canvas is drawing, and stays for
|
||||
anyone who never gets one: reduced motion, no WebGL, no script. -->
|
||||
<div class="hero__layers">
|
||||
<Picture
|
||||
src={background}
|
||||
src={poster}
|
||||
alt=""
|
||||
quality={70}
|
||||
formats={['avif']}
|
||||
@@ -24,6 +27,8 @@ const ui = t(lang);
|
||||
class="hero__img img-cover"
|
||||
pictureAttributes={{ class: 'hero__picture' }}
|
||||
/>
|
||||
<canvas class="hero__field" aria-hidden="true" data-hero-field></canvas>
|
||||
</div>
|
||||
<div class="hero__overlay"></div>
|
||||
</div>
|
||||
|
||||
@@ -55,9 +60,23 @@ const ui = t(lang);
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: 50% 50%;
|
||||
}
|
||||
.hero__layers {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
transform-origin: 50% 60%;
|
||||
animation: hero-settle var(--dur-hero) var(--ease) both;
|
||||
}
|
||||
.hero__field {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
transition: opacity var(--dur-slow) var(--ease);
|
||||
}
|
||||
/* Set by the first drawn frame, so the poster never cuts to black. */
|
||||
.hero__field[data-ready] { opacity: 1; }
|
||||
.hero__overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
@@ -89,7 +108,17 @@ const ui = t(lang);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.hero__img, :global(.hero__img), .hero__line { animation: none; opacity: 1; transform: none; }
|
||||
.hero__layers, .hero__line { animation: none; opacity: 1; transform: none; }
|
||||
.hero__field { display: none; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { startNoiseField } from '../../scripts/noise-field';
|
||||
|
||||
const canvas = document.querySelector<HTMLCanvasElement>('[data-hero-field]');
|
||||
const hero = canvas?.closest<HTMLElement>('.hero');
|
||||
if (canvas && hero && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
startNoiseField(canvas, hero);
|
||||
}
|
||||
</script>
|
||||
Reference in new issue
Block a user