chore: updates to heroimage
e95b3323
2 file(s) · +146 −16
| 1 | + | --- |
|
| 2 | + | import { Image } from "astro:assets"; |
|
| 3 | + | import pastoral from "../../assets/the-pastoral-state.jpg"; |
|
| 4 | + | import savage from "../../assets/the-savage-state.jpg"; |
|
| 5 | + | import consumation from "../../assets/the-consumation-of-empire.jpg"; |
|
| 6 | + | import desolation from "../../assets/desolation.jpg"; |
|
| 7 | + | import destruction from "../../assets/destruction.jpg"; |
|
| 8 | + | ||
| 9 | + | const paintings = [ |
|
| 10 | + | { |
|
| 11 | + | src: savage, |
|
| 12 | + | title: "The Savage State", |
|
| 13 | + | year: "1836", |
|
| 14 | + | description: |
|
| 15 | + | "The first in Thomas Cole's Course of Empire series. Primitive hunters chase prey through untouched wilderness as a storm gathers. Nature is raw, violent, and indifferent to man.", |
|
| 16 | + | }, |
|
| 17 | + | { |
|
| 18 | + | src: pastoral, |
|
| 19 | + | title: "The Pastoral or Arcadian State", |
|
| 20 | + | year: "1836", |
|
| 21 | + | description: |
|
| 22 | + | "The second in Thomas Cole's Course of Empire series. Civilization rises from the wilderness — shepherds graze flocks, a stone temple takes shape, and the land is tamed. Youth and promise hang in the air.", |
|
| 23 | + | }, |
|
| 24 | + | { |
|
| 25 | + | src: consumation, |
|
| 26 | + | title: "The Consummation of Empire", |
|
| 27 | + | year: "1836", |
|
| 28 | + | description: |
|
| 29 | + | "The third and central panel of Thomas Cole's Course of Empire. Empire at its peak — marble columns, gilded processions, and the harbor choked with ships. Triumph so total it can only precede collapse.", |
|
| 30 | + | }, |
|
| 31 | + | { |
|
| 32 | + | src: destruction, |
|
| 33 | + | title: "Destruction", |
|
| 34 | + | year: "1836", |
|
| 35 | + | description: |
|
| 36 | + | "The fourth panel of Thomas Cole's Course of Empire. The empire burns. Invaders pour through the gates, monuments topple into the sea, and the sky turns red with fire and ruin.", |
|
| 37 | + | }, |
|
| 38 | + | { |
|
| 39 | + | src: desolation, |
|
| 40 | + | title: "Desolation", |
|
| 41 | + | year: "1836", |
|
| 42 | + | description: |
|
| 43 | + | "The fifth and final panel of Thomas Cole's Course of Empire. The city is gone. A lone column stands amid ruins reclaimed by vines. No human figures remain. Nature has outlasted everything.", |
|
| 44 | + | }, |
|
| 45 | + | ]; |
|
| 46 | + | ||
| 47 | + | const estHour = parseInt( |
|
| 48 | + | new Date().toLocaleString("en-US", { |
|
| 49 | + | timeZone: "America/New_York", |
|
| 50 | + | hour: "numeric", |
|
| 51 | + | hour12: false, |
|
| 52 | + | }), |
|
| 53 | + | ); |
|
| 54 | + | ||
| 55 | + | const boundaries = [8, 11, 14, 17, 19]; |
|
| 56 | + | const idx = boundaries.findLastIndex((b) => estHour >= b); |
|
| 57 | + | const { src, title, year, description } = paintings[idx === -1 ? 4 : idx]; |
|
| 58 | + | --- |
|
| 59 | + | ||
| 60 | + | <div class="hero-wrapper mb-12" id="hero-wrapper"> |
|
| 61 | + | <Image |
|
| 62 | + | src={src} |
|
| 63 | + | loading="eager" |
|
| 64 | + | alt={`${title} by Thomas Cole`} |
|
| 65 | + | class="aspect-video w-full object-cover" |
|
| 66 | + | /> |
|
| 67 | + | <div class="hero-overlay" id="hero-overlay" aria-hidden="true"> |
|
| 68 | + | <p class="hero-title">{title} <span class="hero-year">({year})</span></p> |
|
| 69 | + | <p class="hero-desc">{description}</p> |
|
| 70 | + | </div> |
|
| 71 | + | </div> |
|
| 72 | + | ||
| 73 | + | <style> |
|
| 74 | + | .hero-wrapper { |
|
| 75 | + | position: relative; |
|
| 76 | + | overflow: hidden; |
|
| 77 | + | } |
|
| 78 | + | ||
| 79 | + | .hero-overlay { |
|
| 80 | + | position: absolute; |
|
| 81 | + | inset: 0; |
|
| 82 | + | background: rgba(0, 0, 0, 0.72); |
|
| 83 | + | display: flex; |
|
| 84 | + | flex-direction: column; |
|
| 85 | + | justify-content: flex-end; |
|
| 86 | + | padding: 1.5rem; |
|
| 87 | + | opacity: 0; |
|
| 88 | + | transition: opacity 0.4s ease; |
|
| 89 | + | pointer-events: none; |
|
| 90 | + | } |
|
| 91 | + | ||
| 92 | + | .hero-overlay.visible { |
|
| 93 | + | opacity: 1; |
|
| 94 | + | } |
|
| 95 | + | ||
| 96 | + | .hero-title { |
|
| 97 | + | font-weight: 600; |
|
| 98 | + | color: #fff; |
|
| 99 | + | font-size: 1rem; |
|
| 100 | + | margin-bottom: 0.35rem; |
|
| 101 | + | } |
|
| 102 | + | ||
| 103 | + | .hero-year { |
|
| 104 | + | font-weight: 400; |
|
| 105 | + | color: #aaa; |
|
| 106 | + | } |
|
| 107 | + | ||
| 108 | + | .hero-desc { |
|
| 109 | + | color: #ccc; |
|
| 110 | + | font-size: 0.8125rem; |
|
| 111 | + | line-height: 1.55; |
|
| 112 | + | max-width: 60ch; |
|
| 113 | + | } |
|
| 114 | + | </style> |
|
| 115 | + | ||
| 116 | + | <script> |
|
| 117 | + | const wrapper = document.getElementById("hero-wrapper"); |
|
| 118 | + | const overlay = document.getElementById("hero-overlay"); |
|
| 119 | + | let timer: ReturnType<typeof setTimeout> | null = null; |
|
| 120 | + | ||
| 121 | + | function show() { |
|
| 122 | + | overlay?.classList.add("visible"); |
|
| 123 | + | } |
|
| 124 | + | ||
| 125 | + | function hide() { |
|
| 126 | + | overlay?.classList.remove("visible"); |
|
| 127 | + | } |
|
| 128 | + | ||
| 129 | + | wrapper?.addEventListener("mouseenter", () => { |
|
| 130 | + | timer = setTimeout(show, 300); |
|
| 131 | + | }); |
|
| 132 | + | ||
| 133 | + | wrapper?.addEventListener("mouseleave", () => { |
|
| 134 | + | if (timer) { |
|
| 135 | + | clearTimeout(timer); |
|
| 136 | + | timer = null; |
|
| 137 | + | } |
|
| 138 | + | hide(); |
|
| 139 | + | }); |
|
| 140 | + | </script> |
| 6 | 6 | import PostPreview from "@/components/blog/PostPreview.astro"; |
|
| 7 | 7 | import SocialList from "@/components/page/SocialList.astro"; |
|
| 8 | 8 | import { sortMDByDate } from "@/utils"; |
|
| 9 | + | import HeroImage from "@/components/page/HeroImage.astro"; |
|
| 9 | 10 | import { Image } from "astro:assets"; |
|
| 10 | - | import pastoral from "../assets/the-pastoral-state.jpg"; |
|
| 11 | - | import savage from "../assets/the-savage-state.jpg"; |
|
| 12 | - | import consumation from "../assets/the-consumation-of-empire.jpg"; |
|
| 13 | - | import desolation from "../assets/desolation.jpg"; |
|
| 14 | - | import destruction from "../assets/destruction.jpg"; |
|
| 15 | - | ||
| 16 | - | const images = [pastoral, savage, consumation, desolation, destruction]; |
|
| 17 | - | const heroImage = images[Math.floor(Math.random() * images.length)]; |
|
| 18 | 11 | ||
| 19 | 12 | const MAX_POSTS = 10; |
|
| 20 | 13 | const allPosts = await getCollection("post"); |
|
| 23 | 16 | --- |
|
| 24 | 17 | ||
| 25 | 18 | <PageLayout meta={{ title: "Steve Simkins" }}> |
|
| 26 | - | <section class="mb-12"> |
|
| 27 | - | <Image src={heroImage} loading="eager" alt="thomas cole painting" class="aspect-video w-full object-cover" /> |
|
| 28 | - | </section> |
|
| 19 | + | <HeroImage /> |
|
| 29 | 20 | <section> |
|
| 30 | 21 | <p class="mb-4"> |
|
| 31 | - | DX Engineer with a passion for developer tooling that advances an |
|
| 32 | - | open web. Currently working at <a |
|
| 22 | + | DX Engineer with a passion for developer tooling that advances an open |
|
| 23 | + | web. Currently working at <a |
|
| 33 | 24 | href="https://stablecore.com" |
|
| 34 | 25 | target="_blank" |
|
| 35 | 26 | rel="noopener noreferrer" |
|
| 36 | 27 | class="style-link">Stablecore</a |
|
| 37 | 28 | > |
|
| 38 | 29 | with other <a href="/projects" class="style-link">projects</a> |
|
| 39 | - | in my spare time. See what I'm up to <a href="/now" class="style-link" |
|
| 40 | - | >now</a |
|
| 41 | - | >! This site catalogs my various writings and interests. |
|
| 30 | + | in my spare time. This site catalogs my various writings and interests. See |
|
| 31 | + | what I'm up to <a href="/now" class="style-link">now</a>! |
|
| 42 | 32 | </p> |
|
| 43 | 33 | <SocialList /> |
|
| 44 | 34 | <p> |
|