Updated headers b2611ded
Steve · 2024-12-08 11:58 7 file(s) · +69 −6
src/components/DecryptingHeader.astro (added) +56 −0
1 +
---
2 +
interface Props {
3 +
	text: string;
4 +
	className?: string;
5 +
}
6 +
7 +
const { text, className = "" } = Astro.props;
8 +
---
9 +
10 +
<h1 class:list={[className]} data-decrypting-text data-text={text}>
11 +
  {text}
12 +
</h1>
13 +
14 +
<script>
15 +
  const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?";
16 +
17 +
  function decrypt(element: Element) {
18 +
    const text = element.getAttribute("data-text") || "";
19 +
    const totalDuration = 1000; // 1.5 seconds
20 +
    const intervalDuration = 30; // Update every 30ms
21 +
    const steps = totalDuration / intervalDuration;
22 +
23 +
    let step = 0;
24 +
    const intervalId = setInterval(() => {
25 +
      if (step < steps) {
26 +
        element.textContent = text
27 +
          .split("")
28 +
          .map((char, index) => {
29 +
            if (index < (step / steps) * text.length) {
30 +
              return char;
31 +
            }
32 +
            return characters[Math.floor(Math.random() * characters.length)];
33 +
          })
34 +
          .join("");
35 +
        step++;
36 +
      } else {
37 +
        clearInterval(intervalId);
38 +
        element.textContent = text;
39 +
      }
40 +
    }, intervalDuration);
41 +
42 +
    return intervalId; // Return the interval ID for cleanup
43 +
  }
44 +
45 +
  function initializeDecryption() {
46 +
    document.querySelectorAll("[data-decrypting-text]").forEach((element) => {
47 +
      decrypt(element);
48 +
    });
49 +
  }
50 +
51 +
  // Initial load
52 +
  initializeDecryption();
53 +
54 +
  // Handle view transitions
55 +
  document.addEventListener('astro:after-swap', initializeDecryption);
56 +
</script>
src/layouts/Base.astro +1 −1
54 54
			// initailse root class attribute
55 55
			root.classList.toggle("dark", isDark);
56 56
		</script>
57 -
		<ViewTransitions />
57 +
		<ViewTransitions fallback="swap" />
58 58
	</head>
59 59
	<body>
60 60
		<SkipLink />
src/pages/about.astro +2 −1
2 2
import PageLayout from "@/layouts/Base";
3 3
import { Image } from "astro:assets";
4 4
import aboutImg from "../assets/pfp.png";
5 +
import DecryptingHeader from "@/components/DecryptingHeader";
5 6
6 7
const meta = {
7 8
	title: "About",
11 12
12 13
<PageLayout meta={meta}>
13 14
	<div class="space-y-6">
14 -
		<h1 class="title">About</h1>
15 +
	 <DecryptingHeader text="About" className="title" />
15 16
		<p>
16 17
			Hey there! My name is Steve and I’m a DX engineer, creator, and tinkerer. I’m currently
17 18
			working at
src/pages/index.astro +3 −2
5 5
import SocialList from "@/components/SocialList";
6 6
import { sortMDByDate } from "@/utils";
7 7
import { Image } from "astro:assets";
8 -
import { DecryptingText } from "src/components/DecryptingText";
8 +
//import { DecryptingText } from "src/components/DecryptingText";
9 +
import DecryptingHeader from "@/components/DecryptingHeader";
9 10
10 11
const MAX_POSTS = 10;
11 12
const allPosts = await getCollection("post");
15 16
16 17
<PageLayout meta={{ title: "Home" }}>
17 18
	<section>
18 -
   <DecryptingText text="Hey There!" className="title mb-6" client:only="react" />
19 +
   <DecryptingHeader text="Hey There!" className="title pb-6" />
19 20
		<p class="mb-4">
20 21
			My name is Steve. I'm a DX Engineer and creator with a desire to
21 22
			help build the future of the web. My latest project is <a
src/pages/posts/[...page].astro +2 −1
6 6
import PostPreview from "@/components/blog/PostPreview";
7 7
import Pagination from "@/components/Paginator";
8 8
import { getUniqueTags, sortMDByDate } from "@/utils";
9 +
import DecryptingHeader from "@/components/DecryptingHeader";
9 10
10 11
export async function getStaticPaths({ paginate }: GetStaticPathsOptions) {
11 12
	const allPosts = await getCollection("post");
44 45
---
45 46
46 47
<PageLayout meta={meta}>
47 -
	<h1 class="title mb-6">Posts</h1>
48 +
  <DecryptingHeader text="Posts" className="title mb-6" />
48 49
	<div class="grid gap-y-16 sm:grid-cols-[3fr_1fr] sm:gap-x-8">
49 50
		<section aria-label="Blog post list">
50 51
			<ul class="space-y-8 text-left">
src/pages/projects.astro +2 −0
2 2
import PageLayout from "@/layouts/Base";
3 3
import ProjectCard from "@/components/ProjectCard";
4 4
import { projects } from "@/data/projects";
5 +
import DecryptingHeader from "@/components/DecryptingHeader";
5 6
6 7
const meta = {
7 8
	title: "Projects",
11 12
12 13
<PageLayout meta={meta}>
13 14
	<div class="flex min-h-screen flex-col items-start justify-start gap-6">
15 +
	<DecryptingHeader text="Projects" className="title" />
14 16
		{projects.map((project) => <ProjectCard content={project} />)}
15 17
	</div>
16 18
</PageLayout>
src/pages/videos.astro +3 −1
1 1
---
2 +
import DecryptingHeader from "@/components/DecryptingHeader";
2 3
import PageLayout from "@/layouts/Base";
4 +
import { DecryptingText } from "src/components/DecryptingText";
3 5
4 6
const meta = {
5 7
	title: "Videos",
11 13
12 14
<PageLayout meta={meta}>
13 15
	<div class="space-y-6">
14 -
		<h1 class="title">Videos</h1>
16 +
	<DecryptingHeader text="Videos" className="title" />
15 17
		<p>Here are some samples of video content I've produced to help users!</p>
16 18
		{
17 19
			videoIds.map((id) => (