Skip to content

Commit cf163f9

Browse files
committed
add SEO tags and replace CDN spline animations with self-hosted ones
1 parent 1cd7c5a commit cf163f9

6 files changed

Lines changed: 213 additions & 360 deletions

File tree

Lines changed: 21 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,33 @@
11
<script lang="ts">
2-
import { onMount, onDestroy } from "svelte";
2+
import { onMount } from "svelte";
3+
import { base } from "$app/paths";
34
4-
let isLoading = $state(true);
5-
let isVisible = $state(false);
6-
let observer: MutationObserver | null = null;
7-
let checkInterval: number | null = null;
8-
let checkCount = 0;
9-
const MAX_CHECKS = 50; // 5 seconds at 100ms intervals
5+
let canvas: HTMLCanvasElement | null = null;
6+
type SplineApp = import("@splinetool/runtime").Application;
107
11-
// Function to hide the Spline logo
12-
const hideSplineLogo = () => {
13-
const viewer = document.querySelector("#fact-token");
14-
if (!viewer?.shadowRoot) return;
8+
let app: SplineApp | null = null;
159
16-
// Try to find and remove the logo
17-
const logo = viewer.shadowRoot.querySelector("a#logo");
18-
if (logo) {
19-
// Apply all styles at once to minimize reflows
20-
(logo as HTMLElement).style.cssText =
21-
"display: none !important; visibility: hidden !important; opacity: 0 !important; pointer-events: none !important;";
22-
logo.remove();
23-
}
10+
onMount(() => {
11+
let isDisposed = false;
2412
25-
// Check if canvas exists to determine if model is loaded
26-
const canvas = viewer.shadowRoot.querySelector("canvas");
27-
if (canvas) {
28-
isLoading = false;
29-
// Once we have the canvas, we can stop checking
30-
if (checkInterval) {
31-
clearInterval(checkInterval);
32-
checkInterval = null;
33-
}
34-
if (observer) {
35-
observer.disconnect();
36-
observer = null;
37-
}
38-
}
39-
};
40-
41-
// Function to ensure we have access to the shadow root
42-
const ensureShadowRootAccess = () => {
43-
const viewer = document.querySelector("#fact-token");
44-
if (!viewer?.shadowRoot) return false;
45-
46-
// Set up the observer if we haven't already
47-
if (!observer) {
48-
observer = new MutationObserver((mutations) => {
49-
// Only process mutations if we're still loading
50-
if (isLoading) {
51-
hideSplineLogo();
52-
}
53-
});
13+
(async () => {
14+
if (!canvas) return;
15+
const { Application } = await import("@splinetool/runtime");
16+
if (isDisposed) return;
17+
app = new Application(canvas);
18+
await app.load(`${base}/token.splinecode`);
19+
})();
5420
55-
// Only observe childList changes in the shadow root
56-
observer.observe(viewer.shadowRoot, {
57-
childList: true,
58-
subtree: true,
59-
});
60-
}
61-
62-
return true;
21+
return () => {
22+
isDisposed = true;
23+
app?.dispose?.();
6324
};
64-
65-
onMount(() => {
66-
// Initial attempt to hide the logo
67-
hideSplineLogo();
68-
69-
// Set up an interval to continuously check for and hide the logo
70-
checkInterval = window.setInterval(() => {
71-
checkCount++;
72-
73-
// Stop checking after MAX_CHECKS to prevent infinite checking
74-
if (checkCount >= MAX_CHECKS) {
75-
if (checkInterval) {
76-
clearInterval(checkInterval);
77-
checkInterval = null;
78-
}
79-
isLoading = false;
80-
return;
81-
}
82-
83-
if (ensureShadowRootAccess()) {
84-
hideSplineLogo();
85-
}
86-
}, 100);
87-
88-
// Set up intersection observer for visibility
89-
const intersectionObserver = new IntersectionObserver(
90-
(entries) => {
91-
isVisible = entries[0].isIntersecting;
92-
},
93-
{ threshold: 0.1 }
94-
);
95-
96-
const container = document.querySelector("#fact-token-container");
97-
if (container) {
98-
intersectionObserver.observe(container);
99-
}
100-
101-
return () => {
102-
if (observer) {
103-
observer.disconnect();
104-
}
105-
if (checkInterval) {
106-
clearInterval(checkInterval);
107-
}
108-
intersectionObserver.disconnect();
109-
};
110-
});
25+
});
11126
</script>
11227

11328
<div
114-
id="fact-token-container"
115-
class="w-48 h-52 pointer-events-none sm:pointer-events-auto mt-8 relative"
29+
id="fact-token-container"
30+
class="w-48 h-52 pointer-events-none sm:pointer-events-auto mt-8 relative"
11631
>
117-
{#if isLoading}
118-
<div class="absolute inset-0 flex items-center justify-center bg-secondary rounded-lg">
119-
<div class="animate-spin rounded-full h-12 w-12 border-b-2 border-primary"></div>
120-
</div>
121-
{/if}
122-
<spline-viewer
123-
id="fact-token"
124-
url="https://prod.spline.design/YkOetzPdSoEqtenO/scene.splinecode"
125-
style="opacity: {isVisible ? 1 : 0}; transition: opacity 0.3s ease-in-out;"
126-
></spline-viewer>
32+
<canvas id="fact-token" bind:this={canvas} class="w-full h-full"></canvas>
12733
</div>

src/lib/components/Hero.svelte

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,71 @@
11
<script lang="ts">
2-
import Link from "$lib/components/Link.svelte";
3-
import PingStatus from "$lib/components/PingStatus.svelte";
4-
import LatestBlogPost from "$lib/components/LatestBlogPost.svelte";
5-
import HighlightedText from "$lib/components/HighlightedText.svelte";
2+
import Link from "$lib/components/Link.svelte";
3+
import PingStatus from "$lib/components/PingStatus.svelte";
4+
import LatestBlogPost from "$lib/components/LatestBlogPost.svelte";
5+
import HighlightedText from "$lib/components/HighlightedText.svelte";
66
</script>
77

88
<div class="relative isolate pt-32 pb-2 lg:pb-20">
9-
<div class="py-16 px-4">
10-
<div class="text-center">
11-
<h1
12-
class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-extrabold font-mulish text-secondary"
13-
>
14-
The Blockchain Oracle of Record
15-
</h1>
16-
<p
17-
class="mt-4 mx-auto px-4 max-w-sm md:max-w-3xl text-pretty font-mulish text-sm lg:text-base font-medium"
18-
>
19-
A decentralized oracle focused on <HighlightedText
20-
>independent verifiability</HighlightedText
21-
>,
22-
<HighlightedText>permanent archival integrity</HighlightedText>, and
23-
<HighlightedText>provable auditability</HighlightedText> raising the bar for trustworthy
24-
smart contract data.
25-
</p>
9+
<div class="py-16 px-4">
10+
<div class="text-center">
11+
<h1
12+
class="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-extrabold font-mulish text-secondary"
13+
>
14+
The Blockchain Oracle of Record
15+
</h1>
16+
<p
17+
class="mt-4 mx-auto px-4 max-w-sm md:max-w-3xl text-pretty font-mulish text-sm lg:text-base font-medium"
18+
>
19+
A decentralized blockchain oracle focused on <HighlightedText
20+
>independent verifiability</HighlightedText
21+
>,
22+
<HighlightedText>permanent archival integrity</HighlightedText>, and
23+
<HighlightedText>provable auditability</HighlightedText> raising the bar
24+
for trustworthy smart contract data.
25+
</p>
2626

27-
<div
28-
class="mt-6 flex gap-y-3 flex-col lg:flex-row items-center justify-center gap-x-6 pb-3"
29-
>
30-
<Link href="https://explorer.orcfax.io" isButton isNewTab>Launch Explorer</Link>
31-
<a
32-
href="https://status.orcfax.io"
33-
class="group inline-flex items-center justify-center gap-x-2 font-semibold text-secondary"
34-
>
35-
<PingStatus color="green" size="sm" />
36-
<span class="underline text-sm">Network Status</span>
37-
<svg
38-
xmlns="http://www.w3.org/2000/svg"
39-
width="24"
40-
height="24"
41-
viewBox="0 0 24 24"
42-
fill="none"
43-
stroke="currentColor"
44-
stroke-width="2"
45-
stroke-linecap="round"
46-
stroke-linejoin="round"
47-
class="size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5"
48-
>
49-
<path d="M5 12h14" />
50-
<path d="m12 5 7 7-7 7" />
51-
</svg>
52-
</a>
53-
</div>
54-
<!-- <div class="my-4">
27+
<div
28+
class="mt-6 flex gap-y-3 flex-col lg:flex-row items-center justify-center gap-x-6 pb-3"
29+
>
30+
<Link href="https://explorer.orcfax.io" isButton isNewTab
31+
>Launch Explorer</Link
32+
>
33+
<a
34+
href="https://status.orcfax.io"
35+
class="group inline-flex items-center justify-center gap-x-2 font-semibold text-secondary"
36+
>
37+
<PingStatus color="green" size="sm" />
38+
<span class="underline text-sm">Network Status</span>
39+
<svg
40+
xmlns="http://www.w3.org/2000/svg"
41+
width="24"
42+
height="24"
43+
viewBox="0 0 24 24"
44+
fill="none"
45+
stroke="currentColor"
46+
stroke-width="2"
47+
stroke-linecap="round"
48+
stroke-linejoin="round"
49+
class="size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5"
50+
>
51+
<path d="M5 12h14" />
52+
<path d="m12 5 7 7-7 7" />
53+
</svg>
54+
</a>
55+
</div>
56+
<!-- <div class="my-4">
5557
<LatestBlogPost />
5658
</div> -->
57-
<div class="mt-4 flex items-center justify-center gap-x-2 text-secondary font-bold">
58-
<span class="text-base">Built on</span>
59-
<img src="/cardano-horizontal-black.svg" alt="Cardano" class="h-5 w-auto" />
60-
</div>
61-
</div>
59+
<div
60+
class="mt-4 flex items-center justify-center gap-x-2 text-secondary font-bold"
61+
>
62+
<span class="text-base">Built on</span>
63+
<img
64+
src="/cardano-horizontal-black.svg"
65+
alt="Cardano"
66+
class="h-5 w-auto"
67+
/>
68+
</div>
6269
</div>
70+
</div>
6371
</div>

0 commit comments

Comments
 (0)