integrate parallax into index and tidy up

This commit is contained in:
badblocks 2026-07-11 11:06:38 -07:00
parent 441056cabc
commit 4bac34bcdd
Signed by: badblocks
SSH key fingerprint: SHA256:hEcM6BP4hKm9F7WsomNuXSBpPn2BSDnFzPSl3y1NerQ
5 changed files with 311 additions and 161 deletions

View file

@ -35,6 +35,10 @@ small.nano {
small.pico { small.pico {
font-size: var(--pt-minion); font-size: var(--pt-minion);
} }
html {
width: 100%;
height: 100%;
}
body { body {
animation: textShadow 1.6s infinite; animation: textShadow 1.6s infinite;
background-color: var(--color-bg); background-color: var(--color-bg);
@ -42,7 +46,7 @@ body {
var(--color-accent-transparent), var(--color-accent-transparent),
black 120% black 120%
); );
background-attachment: fixed;
color: var(--color-fg); color: var(--color-fg);
column-gap: var(--gutter-large); column-gap: var(--gutter-large);
display: grid; display: grid;
@ -53,10 +57,10 @@ body {
padding-inline: var(--page-padding-inline); padding-inline: var(--page-padding-inline);
place-items: center; place-items: center;
position: absolute; position: absolute;
right: 0;
row-gap: var(--stack-large); row-gap: var(--stack-large);
text-shadow: 0 0 5px var(--color-glow); text-shadow: 0 0 5px var(--color-glow);
top: 0; top: 0;
width: 100dvi;
} }
@keyframes flicker { @keyframes flicker {
0% { 0% {
@ -260,6 +264,7 @@ body::after {
bottom: 0; bottom: 0;
right: 0; right: 0;
background: rgba(18, 16, 16, 0.1); background: rgba(18, 16, 16, 0.1);
background-attachment: fixed;
opacity: 0; opacity: 0;
z-index: 2; z-index: 2;
pointer-events: none; pointer-events: none;
@ -285,6 +290,7 @@ body::before {
background-size: background-size:
100% 2px, 100% 2px,
3px 100%; 3px 100%;
background-attachment: fixed;
pointer-events: none; pointer-events: none;
} }
header, header,

View file

@ -27,7 +27,7 @@ const msgValue = pickValue("msg") || (await Astro.session?.get("msg"));
--- ---
<Layout> <Layout>
<title slot="head">Contact</title> <title slot="head">Contact | badblocks.dev</title>
<Fragment slot="head"> <Fragment slot="head">
<script> <script>
import Cap from "@cap.js/widget"; import Cap from "@cap.js/widget";

View file

@ -3,11 +3,307 @@ import Layout from "@layouts/BaseLayout.astro";
--- ---
<Layout> <Layout>
<title slot="head">Home</title> <title slot="head">Home | badblocks.dev</title>
<style>
:root {
--scroll-multiplier: 5;
--theme: winternight;
}
.parallax-theme-winternight {
--layer-0-speed: 6250s;
--layer-1-speed: 1250s;
--layer-2-speed: 500s;
--layer-3-speed: 250s;
--layer-4-speed: 80s;
--layer-0-url: url("/parallax/winternight/0-sky.png");
--layer-1-url: url("/parallax/winternight/1-backmountain.png");
--layer-2-url: url("/parallax/winternight/2-midmountain.png");
--layer-3-url: url("/parallax/winternight/3-midforest.png");
--layer-4-url: url("/parallax/winternight/4-frontfloor.png");
--parallax-width: calc(3800px * 10);
}
.parallax-theme-sunnyvale-forest {
--layer-0-speed: 2000s;
--layer-1-speed: 400s;
--layer-2-speed: 50s;
--layer-0-url: url("/parallax/sunnyvale-forest/0-clouds.png");
--layer-1-url: url("/parallax/sunnyvale-forest/1-mountains.png");
--layer-2-url: url("/parallax/sunnyvale-forest/2-trees.png");
--parallax-width: calc(160px * 200);
}
.parallax-theme-city-destroyed {
--layer-0-speed: 1000s;
--layer-1-speed: 275s;
--layer-2-speed: 250s;
--layer-3-speed: 250s;
--layer-4-speed: 250s;
--layer-5-speed: 100s;
--layer-0-url: url("/parallax/city-destroyed/0-sky.png");
--layer-1-url: url("/parallax/city-destroyed/1-buildingssmoke.png");
--layer-2-url: url("/parallax/city-destroyed/2-water.png");
--layer-3-url: url("/parallax/city-destroyed/3-buildings.png");
--layer-4-url: url("/parallax/city-destroyed/4-buildingreflection.png");
--layer-5-url: url("/parallax/city-destroyed/5-frontsmoke.png");
--parallax-width: calc(3800px * 10);
}
.parallax-theme-city-destroyed .layer.layer-1,
.parallax-theme-city-destroyed .layer.layer-3,
.parallax-theme-city-destroyed .layer.layer-4 {
background-repeat: repeat-x;
}
.parallax-theme-city-destroyed .layer.layer-4 {
background-position-y: 4rem;
}
.parallax-container {
position: relative;
height: 100%;
width: 100%;
overflow: hidden;
z-index: 0;
}
.layer {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: var(--parallax-width);
background-repeat: round;
background-position: bottom;
background-size: contain;
}
.layer-0 {
background-image: var(--layer-0-url);
z-index: 1;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-0-speed))
linear infinite;
}
.layer-1 {
background-image: var(--layer-1-url);
z-index: 2;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-1-speed))
linear infinite;
}
.layer-2 {
background-image: var(--layer-2-url);
z-index: 3;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-2-speed))
linear infinite;
}
.layer-3 {
background-image: var(--layer-3-url);
z-index: 4;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-3-speed))
linear infinite;
}
.layer-4 {
background-image: var(--layer-4-url);
z-index: 5;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-4-speed))
linear infinite;
}
.layer-5 {
background-image: var(--layer-5-url);
z-index: 6;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-5-speed))
linear infinite;
}
@keyframes scroll {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
/*.desktop {
width: 100%;
}
.desktop-monitor {
margin: 10px auto 0px auto;
width: 330px;
height: 230px;
border: 4px solid #34495e;
border-radius: 15px;
}
.desktop-audio {
border: 2px solid #34495e;
width: 10px;
height: 8px;
border-radius: 10px;
margin: 6px auto 0px auto;
}
.desktop-screen {
margin: 5px auto 0px auto;
border: 3px solid #34495e;
border-radius: 5px;
width: 305px;
height: 195px;
background-color: black;
object-fit: contain;
position: relative;
}
.desktop-screen-text {
position: absolute;
top: 0;
right: 0.25em;
}
.desktop-keyboard {
width: 360px;
height: 20px;
border: 4px solid #34495e;
border-radius: 2px;
margin: -4px auto 2px auto;
}
.desktop-keyboard-detail {
border: 1px solid #34495e;
width: 50px;
height: 8px;
border-radius: 10px;
margin: 0px auto 0px auto;
}
.desktop-keyboard-top {
width: 360px;
height: 8px;
background-color: #34495e;
border-radius: 2px;
margin: -2px auto 4px auto;
clip-path: polygon(10% 0, 90% 0, 100% 100%, 0 100%);
}*/
.desktop {
width: 100%;
container-type: inline-size; /* only needed for the cqi strokes */
}
.desktop,
.desktop :where(div) {
box-sizing: border-box;
}
.desktop-monitor {
width: 92%;
margin: 3% auto 0;
padding-bottom: 2%; /* chin below the screen */
border: max(1px, 1.1cqi) solid #34495e;
border-radius: 4cqi;
}
.desktop-audio {
width: 3%;
aspect-ratio: 5 / 4;
margin: 2% auto 0;
border: max(1px, 0.5cqi) solid #34495e;
border-radius: 999px;
}
.desktop-screen {
width: 92.5%;
aspect-ratio: 305 / 195; /* just a shape ratio, tune freely */
margin: 1.5% auto 0;
border: max(1px, 0.8cqi) solid #34495e;
border-radius: 1.4cqi;
background-color: black;
position: relative;
}
.desktop-screen-text {
position: absolute;
top: 0;
right: 0.25em;
}
.desktop-keyboard-top {
width: 100%;
aspect-ratio: 45 / 1;
margin: -0.5% auto 1%;
background-color: #34495e;
border-radius: 0.5cqi;
clip-path: polygon(10% 0, 90% 0, 100% 100%, 0 100%);
}
.desktop-keyboard {
width: 100%;
aspect-ratio: 13 / 1;
margin: -1% auto 0.5%;
border: max(1px, 1.1cqi) solid #34495e;
border-radius: 0.5cqi;
}
.desktop-keyboard-detail {
width: 14%;
aspect-ratio: 25 / 4;
margin: 0 auto;
border: 1px solid #34495e;
border-radius: 999px;
}
.sided {
display: flex;
flex-direction: row;
align-items: center;
}
.sided > div {
flex: auto;
}
</style>
<Fragment slot="main"> <Fragment slot="main">
<article id="hero"> <article
<h2>Hi, I'm badblocks!</h2> id="hero"
<p>I ♥ building websites and making things!</p> x-data="{
themes: [
{ value: 'winternight', label: 'Winternight' },
{ value: 'sunnyvale-forest', label: 'SunnyVale' },
{ value: 'city-destroyed', label: 'Apocalypse' },
],
index: 0,
get theme() { return this.themes[this.index].value },
next() { this.index = (this.index + 1) % this.themes.length },
}"
>
<div class="sided">
<div>
<h2>Hi, I'm badblocks!</h2>
<p>I ♥ building websites and making things!</p>
</div><div class="desktop">
<div class="desktop-monitor">
<div class="desktop-audio"></div>
<div class="desktop-screen" @click="next()">
<div
class="parallax-container"
:class="'parallax-theme-' + theme"
>
<div class="layer layer-0"></div>
<div class="layer layer-1"></div>
<div class="layer layer-2"></div>
<div class="layer layer-3"></div>
<div class="layer layer-4"></div>
<div class="layer layer-5"></div>
</div>
<div class="desktop-screen-text" x-text="themes[index].label">
</div>
</div>
</div>
<div class="desktop-keyboard-top"></div>
<div class="desktop-keyboard">
<div class="desktop-keyboard-detail"></div>
</div>
</div>
</div>
</article> </article>
</Fragment> </Fragment>
</Layout> </Layout>

View file

@ -21,7 +21,7 @@ const license_file_contents = txtToHtml(
--- ---
<Layout> <Layout>
<title slot="head">LICENSE</title> <title slot="head">LICENSE | badblocks.dev</title>
<Fragment slot="main"> <Fragment slot="main">
<header> <header>
<h1> <h1>
@ -30,6 +30,6 @@ const license_file_contents = txtToHtml(
> >
</h1> </h1>
</header> </header>
<p set:html={license_file_contents} /> <div style="font-size: medium;" set:html={license_file_contents} />
</Fragment> </Fragment>
</Layout> </Layout>

View file

@ -1,152 +0,0 @@
---
import Layout from "@layouts/BaseLayout.astro";
---
<Layout>
<title slot="head">Parallax Demo</title>
<style>
:root {
--scroll-multiplier: 5;
--theme: winternight;
}
.parallax-theme-winternight {
--layer-0-speed: 6250s;
--layer-1-speed: 1250s;
--layer-2-speed: 500s;
--layer-3-speed: 250s;
--layer-4-speed: 80s;
--layer-0-url: url("/parallax/winternight/0-sky.png");
--layer-1-url: url("/parallax/winternight/1-backmountain.png");
--layer-2-url: url("/parallax/winternight/2-midmountain.png");
--layer-3-url: url("/parallax/winternight/3-midforest.png");
--layer-4-url: url("/parallax/winternight/4-frontfloor.png");
--parallax-width: calc(3800px * 10);
}
.parallax-theme-sunnyvale-forest {
--layer-0-speed: 2000s;
--layer-1-speed: 400s;
--layer-2-speed: 50s;
--layer-0-url: url("/parallax/sunnyvale-forest/0-clouds.png");
--layer-1-url: url("/parallax/sunnyvale-forest/1-mountains.png");
--layer-2-url: url("/parallax/sunnyvale-forest/2-trees.png");
--parallax-width: calc(160px * 200);
}
.parallax-theme-city-destroyed {
--layer-0-speed: 1000s;
--layer-1-speed: 275s;
--layer-2-speed: 250s;
--layer-3-speed: 250s;
--layer-4-speed: 250s;
--layer-5-speed: 100s;
--layer-0-url: url("/parallax/city-destroyed/0-sky.png");
--layer-1-url: url("/parallax/city-destroyed/1-buildingssmoke.png");
--layer-2-url: url("/parallax/city-destroyed/2-water.png");
--layer-3-url: url("/parallax/city-destroyed/3-buildings.png");
--layer-4-url: url("/parallax/city-destroyed/4-buildingreflection.png");
--layer-5-url: url("/parallax/city-destroyed/5-frontsmoke.png");
--parallax-width: calc(3800px * 10);
}
.parallax-theme-city-destroyed .layer.layer-1,
.parallax-theme-city-destroyed .layer.layer-3,
.parallax-theme-city-destroyed .layer.layer-4 {
background-repeat: repeat-x;
}
.parallax-theme-city-destroyed .layer.layer-4 {
background-position-y: 16rem;
}
.parallax-container {
position: relative;
height: 30rem;
width: 100%;
overflow: hidden;
z-index: 0;
}
.layer {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: var(--parallax-width);
background-repeat: round;
background-position: bottom;
background-size: contain;
}
.layer-0 {
background-image: var(--layer-0-url);
z-index: 1;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-0-speed))
linear infinite;
}
.layer-1 {
background-image: var(--layer-1-url);
z-index: 2;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-1-speed))
linear infinite;
}
.layer-2 {
background-image: var(--layer-2-url);
z-index: 3;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-2-speed))
linear infinite;
}
.layer-3 {
background-image: var(--layer-3-url);
z-index: 4;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-3-speed))
linear infinite;
}
.layer-4 {
background-image: var(--layer-4-url);
z-index: 5;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-4-speed))
linear infinite;
}
.layer-5 {
background-image: var(--layer-5-url);
z-index: 6;
animation: scroll calc(var(--scroll-multiplier) * var(--layer-5-speed))
linear infinite;
}
@keyframes scroll {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
</style>
<Fragment slot="main">
<article id="hero" x-data="{ theme: 'winternight'}">
<div class="parallax-container" :class="'parallax-theme-' + theme">
<div class="layer layer-0"></div>
<div class="layer layer-1"></div>
<div class="layer layer-2"></div>
<div class="layer layer-3"></div>
<div class="layer layer-4"></div>
<div class="layer layer-5"></div>
</div>
<h2>Parallax Demo</h2>
<p>Pardon the dust!</p>
<select id="theme" x-model="theme">
<option value="winternight">Winternight</option>
<option value="sunnyvale-forest">SunnyVale</option>
<option value="city-destroyed">Apocalypse</option>
</select>
</article>
</Fragment>
</Layout>