First draft
This commit is contained in:
202
src/layouts/MainPageLayout.astro
Normal file
202
src/layouts/MainPageLayout.astro
Normal file
@@ -0,0 +1,202 @@
|
||||
---
|
||||
import CommonLayout from "./CommonLayout.astro";
|
||||
import slideColors from "../content/slide-colors.json"
|
||||
|
||||
export interface Props {
|
||||
title: string;
|
||||
numberOfSlides?: number;
|
||||
}
|
||||
|
||||
const { title, numberOfSlides } = Astro.props;
|
||||
|
||||
const prefixedSlideColors = Object.entries(slideColors).reduce<Record<string, any>>((acc, [key, values]) => {
|
||||
Object.entries(values).forEach(([subKey, value]) => {
|
||||
acc[`${key.toString()}-${subKey.toString()}`] = value;
|
||||
});
|
||||
return acc;
|
||||
}, {});
|
||||
---
|
||||
|
||||
<CommonLayout title={title}>
|
||||
<body>
|
||||
<aside id="scroll-indicator" role="contentinfo">
|
||||
<div id="scroll-indicator-container">
|
||||
<span class="indicator"></span>
|
||||
{ [...Array(numberOfSlides ?? 4)].map(() => (<span class="shadow"></span>)) }
|
||||
</div>
|
||||
</aside>
|
||||
<slot name="head" />
|
||||
<slot />
|
||||
</body>
|
||||
</CommonLayout>
|
||||
|
||||
<style is:global>
|
||||
@property --text-color {
|
||||
syntax: "<color>";
|
||||
inherits: true;
|
||||
initial-value: #ddd;
|
||||
}
|
||||
|
||||
@property --text-color-dark {
|
||||
syntax: "<color>";
|
||||
inherits: true;
|
||||
initial-value: oklch(from var(--text-color) l c h / 0.8);
|
||||
}
|
||||
|
||||
@property --glass-color {
|
||||
syntax: "<color>";
|
||||
inherits: true;
|
||||
initial-value: hsl(283, 86%, 20%);
|
||||
}
|
||||
|
||||
@property --background-color {
|
||||
syntax: "<color>";
|
||||
inherits: true;
|
||||
initial-value: #0d0117;
|
||||
}
|
||||
|
||||
@property --accent-color {
|
||||
syntax: "<color>";
|
||||
inherits: true;
|
||||
initial-value: hsl(282deg 67% 85%);
|
||||
}
|
||||
|
||||
body {
|
||||
--text-color: var(--default-text-color);
|
||||
--text-color-dark: oklch(from var(--text-color) l c h / 0.8);
|
||||
--background-color: #0d0117;
|
||||
--accent-color: hsl(282deg 67% 85%);
|
||||
--glass-color: hsl(from var(--accent-color) h s 20%);
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" define:vars={prefixedSlideColors}>
|
||||
html {
|
||||
height: 100dvh;
|
||||
width: 100dvw;
|
||||
overflow-y: hidden;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
min-height: 100dvh;
|
||||
width: 100dvw;
|
||||
min-width: max-content;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: start;
|
||||
justify-content: start;
|
||||
scroll-snap-type: y mandatory;
|
||||
scroll-snap-align: start;
|
||||
scroll-timeline: --root-scroll-timeline;
|
||||
|
||||
scrollbar-width: none; /* Firefox */
|
||||
&::-webkit-scrollbar {
|
||||
width: 0; /* Chrome, Safari, Opera */
|
||||
}
|
||||
|
||||
& > :global(*):not(#scroll-indicator) {
|
||||
flex-shrink: 0;
|
||||
scroll-snap-align: start;
|
||||
width: 100dvw;
|
||||
height: 100dvh;
|
||||
}
|
||||
}
|
||||
|
||||
#scroll-indicator {
|
||||
z-index: 1000;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: none;
|
||||
|
||||
#scroll-indicator-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
.shadow, .indicator {
|
||||
display: inline-block;
|
||||
height: 1em;
|
||||
aspect-ratio: 1 / 1;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 50%;
|
||||
filter: blur(0.1em);
|
||||
}
|
||||
|
||||
.indicator {
|
||||
position: absolute;
|
||||
top: calc(100% - 1em);
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@supports (animation-timeline: scroll()) {
|
||||
#scroll-indicator {
|
||||
display: block;
|
||||
|
||||
& .indicator {
|
||||
animation: scroll-indicator-animation linear;
|
||||
animation-timeline: --root-scroll-timeline;
|
||||
animation-duration: 1ms;
|
||||
|
||||
@keyframes scroll-indicator-animation {
|
||||
0% {
|
||||
top: 0;
|
||||
}
|
||||
100% {
|
||||
top: calc(100% - 1em);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
@supports (animation-timeline: scroll()) {
|
||||
body {
|
||||
animation: color-fade linear;
|
||||
animation-timeline: --root-scroll-timeline;
|
||||
animation-duration: 1ms;
|
||||
|
||||
@keyframes color-fade {
|
||||
0%,100% {
|
||||
--accent-color: #ddd;
|
||||
--text-color: #ddd;
|
||||
}
|
||||
8.33%,
|
||||
16.67%,
|
||||
33.33%,
|
||||
41.67%,
|
||||
58.33%,
|
||||
66.67%,
|
||||
83.33%,
|
||||
91.67% {
|
||||
--accent-color: #000;
|
||||
--glass-color: #000;
|
||||
--text-color: #000;
|
||||
}
|
||||
25% {
|
||||
--accent-color: hsl(191, 88%, 81%);
|
||||
--glass-color: hsl(191, 88%, 20%);
|
||||
--text-color: #ddd;
|
||||
}
|
||||
50% {
|
||||
--accent-color: hsl(31deg 100% 85%);
|
||||
--glass-color: hsl(31deg 100% 20%);
|
||||
--text-color: #ddd;
|
||||
}
|
||||
75% {
|
||||
--accent-color: hsl(347deg 89% 85%);
|
||||
--glass-color: hsl(347deg 89% 20%);
|
||||
--text-color: #ddd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user