get routing working, add index for poetry, list first 6 poems on index, let each take you to their page with the poem's content
This commit is contained in:
parent
2cf484aa46
commit
3d22344e7f
|
@ -0,0 +1 @@
|
|||
nodejs 20.13.1
|
|
@ -12,6 +12,7 @@
|
|||
"@threlte/core": "^7.3.0",
|
||||
"@threlte/extras": "^8.11.2",
|
||||
"@threlte/rapier": "^2.0.0",
|
||||
"mdsvex": "^0.11.0",
|
||||
"three": "^0.159.0",
|
||||
"three-inspect": "^0.4.5"
|
||||
},
|
||||
|
@ -1986,6 +1987,11 @@
|
|||
"meshoptimizer": "~0.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/unist": {
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
|
||||
"integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA=="
|
||||
},
|
||||
"node_modules/@types/webxr": {
|
||||
"version": "0.5.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.15.tgz",
|
||||
|
@ -5028,6 +5034,20 @@
|
|||
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
|
||||
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="
|
||||
},
|
||||
"node_modules/mdsvex": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/mdsvex/-/mdsvex-0.11.0.tgz",
|
||||
"integrity": "sha512-gJF1s0N2nCmdxcKn8HDn0LKrN8poStqAicp6bBcsKFd/zkUBGLP5e7vnxu+g0pjBbDFOscUyI1mtHz+YK2TCDw==",
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.3",
|
||||
"prism-svelte": "^0.4.7",
|
||||
"prismjs": "^1.17.1",
|
||||
"vfile-message": "^2.0.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": ">=3 <5"
|
||||
}
|
||||
},
|
||||
"node_modules/meow": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz",
|
||||
|
@ -5962,6 +5982,19 @@
|
|||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prism-svelte": {
|
||||
"version": "0.4.7",
|
||||
"resolved": "https://registry.npmjs.org/prism-svelte/-/prism-svelte-0.4.7.tgz",
|
||||
"integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ=="
|
||||
},
|
||||
"node_modules/prismjs": {
|
||||
"version": "1.29.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
|
||||
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/pseudomap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||
|
@ -7874,6 +7907,18 @@
|
|||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/unist-util-stringify-position": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz",
|
||||
"integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
|
@ -7936,6 +7981,19 @@
|
|||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vfile-message": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz",
|
||||
"integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
|
||||
"dependencies": {
|
||||
"@types/unist": "^2.0.0",
|
||||
"unist-util-stringify-position": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.2.10",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz",
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
"@threlte/core": "^7.3.0",
|
||||
"@threlte/extras": "^8.11.2",
|
||||
"@threlte/rapier": "^2.0.0",
|
||||
"mdsvex": "^0.11.0",
|
||||
"three": "^0.159.0",
|
||||
"three-inspect": "^0.4.5"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<script lang="ts">
|
||||
import { T, useTask, useThrelte } from '@threlte/core';
|
||||
import { World } from '@threlte/rapier';
|
||||
import { Inspector } from 'three-inspect';
|
||||
import { dev } from '$app/environment';
|
||||
import SpaceSkysphere from './SpaceSkysphere.svelte';
|
||||
import { Group, type Object3DEventMap } from 'three';
|
||||
import DollyCam from './DollyCam.svelte';
|
||||
import Planet from '$lib/components/scenes/app/Planet.svelte';
|
||||
|
||||
const { invalidate } = useThrelte();
|
||||
let spaceObjects: Group<Object3DEventMap>;
|
||||
|
||||
useTask(
|
||||
'updateSpaceObjects',
|
||||
(delta) => {
|
||||
if (!spaceObjects) return;
|
||||
spaceObjects.rotation.y += 0.3 * delta;
|
||||
spaceObjects.position.y = Math.sin(spaceObjects.rotation.y);
|
||||
|
||||
invalidate();
|
||||
},
|
||||
{ autoInvalidate: false }
|
||||
);
|
||||
</script>
|
||||
|
||||
<World gravity={[0, 0, 0]}>
|
||||
<DollyCam />
|
||||
|
||||
<T.Group bind:ref={spaceObjects}>
|
||||
<SpaceSkysphere size={100} count={500} />
|
||||
|
||||
<Planet />
|
||||
|
||||
<slot />
|
||||
</T.Group>
|
||||
</World>
|
||||
|
||||
{#if false}
|
||||
<Inspector />
|
||||
{/if}
|
|
@ -0,0 +1,26 @@
|
|||
<!-- src/lib/CanvasLayout.svelte -->
|
||||
<script lang="ts">
|
||||
import { Canvas } from '@threlte/core';
|
||||
</script>
|
||||
|
||||
<div class="canvas">
|
||||
<Canvas>
|
||||
<slot />
|
||||
</Canvas>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgb(0, 36, 6);
|
||||
background: linear-gradient(180deg, rgba(0, 36, 6, 1) 0%, rgba(0, 0, 0, 1) 100%);
|
||||
position: absolute;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,44 @@
|
|||
<script lang="ts">
|
||||
import { T, useTask, useThrelte } from '@threlte/core';
|
||||
import { onMount } from 'svelte';
|
||||
import { PerspectiveCamera, Vector3 } from 'three';
|
||||
const { invalidate } = useThrelte();
|
||||
|
||||
let camLookatPosition: Vector3 = new Vector3();
|
||||
let camCurrentPosition: Vector3 = new Vector3();
|
||||
let camDamping: number = 1;
|
||||
let camera: PerspectiveCamera;
|
||||
|
||||
const handleMouseMove = (event: MouseEvent) => {
|
||||
// normalize the mouse position to [-1, 1], and smoothly interpolate the camera's lookAt position
|
||||
camLookatPosition.set(
|
||||
(event.clientX / window.innerWidth) * 2 - 1,
|
||||
-(event.clientY / window.innerHeight) * 2 + 1,
|
||||
0
|
||||
);
|
||||
};
|
||||
|
||||
useTask(
|
||||
'dollyCam',
|
||||
(delta) => {
|
||||
if (!camera) return;
|
||||
camCurrentPosition.lerp(camLookatPosition, camDamping * delta);
|
||||
camera.lookAt(camCurrentPosition);
|
||||
|
||||
if (camera && camCurrentPosition.distanceTo(camLookatPosition) > 0.1) {
|
||||
invalidate();
|
||||
}
|
||||
},
|
||||
{ autoInvalidate: false }
|
||||
);
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener('mousemove', handleMouseMove);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('mousemove', handleMouseMove);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<T.PerspectiveCamera position.z={25} makeDefault fov={50} far={10000} bind:ref={camera} />
|
|
@ -0,0 +1,51 @@
|
|||
<script lang="ts">
|
||||
import { HTML } from '@threlte/extras';
|
||||
import { Attractor } from '@threlte/rapier';
|
||||
|
||||
export let position: [number, number, number] = [0, 0, 0];
|
||||
export let range: number = 100;
|
||||
export let clickHandler: (() => void) | undefined = undefined;
|
||||
export let htmlContent: HTMLElement | string = 'Hello!';
|
||||
export let href: string = '/';
|
||||
|
||||
let isHovering = false;
|
||||
let isPointerDown = false;
|
||||
|
||||
const onClick = () => {
|
||||
console.log('clicked!');
|
||||
if (clickHandler) {
|
||||
clickHandler();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<HTML position.x={position[0]} position.y={position[1]} position.z={position[2]}>
|
||||
<a
|
||||
{href}
|
||||
on:pointerenter={() => (isHovering = true)}
|
||||
on:pointerleave={() => {
|
||||
isPointerDown = false;
|
||||
isHovering = false;
|
||||
}}
|
||||
on:pointerdown={() => (isPointerDown = true)}
|
||||
on:pointerup={() => (isPointerDown = false)}
|
||||
on:pointercancel={() => {
|
||||
isPointerDown = false;
|
||||
isHovering = false;
|
||||
}}
|
||||
on:click={onClick}
|
||||
class="bg-green-700 px-3 py-3 text-white opacity-50 hover:opacity-90 active:opacity-100"
|
||||
style="transform: translate(-50%, 50%); display: block;"
|
||||
>
|
||||
{htmlContent}
|
||||
</a>
|
||||
</HTML>
|
||||
|
||||
<Attractor
|
||||
position.x={position[0]}
|
||||
position.y={position[1]}
|
||||
position.z={position[2]}
|
||||
{range}
|
||||
strength={isHovering ? 1 : 0}
|
||||
gravityType={'static'}
|
||||
/>
|
|
@ -0,0 +1,19 @@
|
|||
<script lang="ts" context="module">
|
||||
import { T } from '@threlte/core';
|
||||
import { Attractor, Collider, RigidBody } from '@threlte/rapier';
|
||||
import { MeshBasicMaterial, SphereGeometry } from 'three';
|
||||
const geometry = new SphereGeometry(1, 8, 4);
|
||||
const material = new MeshBasicMaterial({ color: '#339933', wireframe: true });
|
||||
const position: [number, number, number] = [0, 0, 0];
|
||||
const scale: number = 2;
|
||||
const offset = position.map((el) => el + 1.5);
|
||||
</script>
|
||||
|
||||
<Attractor {position} range={100} strength={0.3} gravityType={'linear'} />
|
||||
|
||||
<T.Group position.x={-offset[0]} position.y={-offset[1]} position.z={offset[2]}>
|
||||
<RigidBody linearDamping={0.3}>
|
||||
<Collider shape="ball" args={[scale]} mass={scale} />
|
||||
<T.Mesh scale={[scale, scale, scale]} {geometry} {material} />
|
||||
</RigidBody>
|
||||
</T.Group>
|
|
@ -5,7 +5,7 @@
|
|||
import { Studio } from '@threlte/theatre';
|
||||
</script>
|
||||
|
||||
<Studio enabled={false} />
|
||||
<Studio enabled={dev} />
|
||||
|
||||
<Canvas>
|
||||
<Spinners />
|
||||
|
|
|
@ -8,18 +8,18 @@
|
|||
|
||||
let sequence: SequenceController;
|
||||
|
||||
let box: Mesh;
|
||||
let ball: Mesh;
|
||||
let spotlight: SpotLight;
|
||||
let lastBoxPosition = new Vector3();
|
||||
let currentBoxPosition = new Vector3();
|
||||
let lastBallPosition = new Vector3();
|
||||
let currentBallPosition = new Vector3();
|
||||
let config = spinnersJson as IProjectConfig;
|
||||
|
||||
const boxMoved: any = (props: { position: { x: number; y: number; z: number } }) => {
|
||||
if (box && spotlight) {
|
||||
const ballMoved: any = (props: { position: { x: number; y: number; z: number } }) => {
|
||||
if (ball && spotlight) {
|
||||
const { x, y, z } = props.position;
|
||||
currentBoxPosition.set(x, y, z);
|
||||
spotlight.lookAt(currentBoxPosition);
|
||||
lastBoxPosition.copy(currentBoxPosition);
|
||||
currentBallPosition.set(x, y, z);
|
||||
spotlight.lookAt(currentBallPosition);
|
||||
lastBallPosition.copy(currentBallPosition);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -33,10 +33,10 @@
|
|||
<!-- create a T.SpotLight that looks at box-->
|
||||
<T.SpotLight position={[0, 5, 3]} intensity={10} bind:ref={spotlight}></T.SpotLight>
|
||||
|
||||
<SheetObject key="Box" let:Transform let:Sync on:change={boxMoved}>
|
||||
<SheetObject key="Box" let:Transform let:Sync on:change={ballMoved}>
|
||||
<Transform>
|
||||
<T.Mesh position.y={0.5} bind:ref={box}>
|
||||
<T.BoxGeometry args={[1, 1, 1]} />
|
||||
<T.Mesh position.y={0.5} bind:ref={ball}>
|
||||
<T.SphereGeometry args={[1, 8, 4]} />
|
||||
<T.MeshStandardMaterial color="#b00d03">
|
||||
<Sync color roughness metalness />
|
||||
</T.MeshStandardMaterial>
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
<script lang="ts">
|
||||
import { Canvas, T } from '@threlte/core';
|
||||
import { OrbitControls } from '@threlte/extras';
|
||||
import OrbitingSpheres from '$lib/components/scenes/home/OrbitingSpheres.svelte';
|
||||
import { World } from '@threlte/rapier';
|
||||
import { Inspector } from 'three-inspect';
|
||||
import { dev } from '$app/environment';
|
||||
import SpaceSkysphere from './SpaceSkysphere.svelte';
|
||||
</script>
|
||||
|
||||
<Canvas>
|
||||
<World gravity={[0, 0, 0]}>
|
||||
<T.PerspectiveCamera position.y={15} position.z={25} makeDefault fov={70} far={10000}>
|
||||
<OrbitControls
|
||||
enableZoom={false}
|
||||
enablePan={false}
|
||||
enableRotate={false}
|
||||
enableDamping
|
||||
target.y={0}
|
||||
autoRotate
|
||||
/>
|
||||
</T.PerspectiveCamera>
|
||||
|
||||
<SpaceSkysphere size={100} count={500} />
|
||||
|
||||
<OrbitingSpheres position={[0, 0, 0]} range={10} />
|
||||
</World>
|
||||
|
||||
{#if dev}
|
||||
<Inspector />
|
||||
{/if}
|
||||
</Canvas>
|
|
@ -1,86 +0,0 @@
|
|||
<script lang="ts" context="module">
|
||||
const geometry = new SphereGeometry(1, 8, 4);
|
||||
const material = new MeshBasicMaterial({ color: '#339933' });
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { T } from '@threlte/core';
|
||||
import { HTML } from '@threlte/extras';
|
||||
import { Attractor, Collider, RigidBody } from '@threlte/rapier';
|
||||
import { MeshBasicMaterial, SphereGeometry, Vector3 } from 'three';
|
||||
|
||||
export let range: number = 10;
|
||||
export let position: [number, number, number] = [0, 0, 0];
|
||||
let isHovering = false;
|
||||
let isPointerDown = false;
|
||||
const bodyPositions = [
|
||||
new Vector3(position[0] - range, position[0] - range, position[0] - range).toArray(),
|
||||
new Vector3(position[1] + range / 2, position[1] + range, position[1] + range).toArray(),
|
||||
new Vector3(position[2] + range, position[2] - range / 2, position[2] + range).toArray()
|
||||
];
|
||||
|
||||
const getId = () => {
|
||||
return Math.random().toString(16).slice(2);
|
||||
};
|
||||
|
||||
const getRandomSize = (): number => {
|
||||
return Math.random() / 4 + 0.25;
|
||||
};
|
||||
|
||||
const generateBodies = (c: number) => {
|
||||
return Array(c)
|
||||
.fill('x')
|
||||
.map((_, index) => {
|
||||
return {
|
||||
id: getId(),
|
||||
position: bodyPositions[index],
|
||||
size: getRandomSize()
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const onClick = () => {
|
||||
console.log('clicked');
|
||||
};
|
||||
|
||||
$: bodies = generateBodies(2);
|
||||
</script>
|
||||
|
||||
<HTML position.x={position[0]} position.y={position[1]} position.z={position[2]}>
|
||||
<button
|
||||
on:pointerenter={() => (isHovering = true)}
|
||||
on:pointerleave={() => {
|
||||
isPointerDown = false;
|
||||
isHovering = false;
|
||||
}}
|
||||
on:pointerdown={() => (isPointerDown = true)}
|
||||
on:pointerup={() => (isPointerDown = false)}
|
||||
on:pointercancel={() => {
|
||||
isPointerDown = false;
|
||||
isHovering = false;
|
||||
}}
|
||||
on:click={onClick}
|
||||
class="rounded-full bg-orange-500 px-3 text-white hover:opacity-90 active:opacity-70"
|
||||
>
|
||||
Hello!
|
||||
</button>
|
||||
</HTML>
|
||||
|
||||
<Attractor
|
||||
position.x={position[0]}
|
||||
position.y={position[1]}
|
||||
position.z={position[2]}
|
||||
range={200}
|
||||
strength={isHovering ? 1 : 0.1}
|
||||
gravityType={'linear'}
|
||||
/>
|
||||
|
||||
{#each bodies as body (body.id)}
|
||||
<T.Group position={body.position}>
|
||||
<RigidBody>
|
||||
<Collider shape="ball" args={[body.size]} mass={body.size} />
|
||||
<Attractor range={50} strength={1} gravityType={'newtonian'} />
|
||||
<T.Mesh scale={[body.size, body.size, body.size]} {geometry} {material} />
|
||||
</RigidBody>
|
||||
</T.Group>
|
||||
{/each}
|
|
@ -0,0 +1,63 @@
|
|||
<script context="module">
|
||||
import { tick } from 'svelte';
|
||||
|
||||
/**
|
||||
* Usage: <div use:portal={'css selector'}> or <div use:portal={document.body}>
|
||||
*
|
||||
* @param {HTMLElement} el
|
||||
* @param {HTMLElement|string} target DOM Element or CSS Selector
|
||||
*/
|
||||
export function portal(el, target = 'body') {
|
||||
let targetEl;
|
||||
/**
|
||||
* @param {string | HTMLElement} newTarget
|
||||
*/
|
||||
async function update(newTarget) {
|
||||
target = newTarget;
|
||||
if (typeof target === 'string') {
|
||||
targetEl = document.querySelector(target);
|
||||
if (targetEl === null) {
|
||||
await tick();
|
||||
targetEl = document.querySelector(target);
|
||||
}
|
||||
if (targetEl === null) {
|
||||
throw new Error(`No element found matching css selector: "${target}"`);
|
||||
}
|
||||
} else if (target instanceof HTMLElement) {
|
||||
targetEl = target;
|
||||
} else {
|
||||
throw new TypeError(
|
||||
`Unknown portal target type: ${
|
||||
target === null ? 'null' : typeof target
|
||||
}. Allowed types: string (CSS selector) or HTMLElement.`
|
||||
);
|
||||
}
|
||||
targetEl.appendChild(el);
|
||||
el.hidden = false;
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
if (el.parentNode) {
|
||||
el.parentNode.removeChild(el);
|
||||
}
|
||||
}
|
||||
|
||||
update(target);
|
||||
return {
|
||||
update,
|
||||
destroy
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* DOM Element or CSS Selector
|
||||
* @type { HTMLElement|string}
|
||||
*/
|
||||
export let target = 'body';
|
||||
</script>
|
||||
|
||||
<div use:portal={target} hidden style="display: contents;">
|
||||
<slot />
|
||||
</div>
|
|
@ -0,0 +1,80 @@
|
|||
export interface Metadata {
|
||||
title: string;
|
||||
date: string;
|
||||
content: string;
|
||||
categories?: string[];
|
||||
section?: SectionKey;
|
||||
}
|
||||
|
||||
export interface Section {
|
||||
poetry: 'poetry';
|
||||
thoughts: 'thoughts';
|
||||
projects: 'projects';
|
||||
}
|
||||
|
||||
type SectionKey = keyof Section;
|
||||
|
||||
export interface Post {
|
||||
meta: Metadata;
|
||||
path: string;
|
||||
}
|
||||
|
||||
interface Data {
|
||||
metadata: Metadata;
|
||||
}
|
||||
|
||||
function isData(obj: unknown): obj is Data {
|
||||
if (typeof obj !== 'object' || obj === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const dataObj = obj as Data;
|
||||
|
||||
return (
|
||||
'metadata' in dataObj &&
|
||||
typeof dataObj.metadata.title === 'string' &&
|
||||
typeof dataObj.metadata.date === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
export const fetchMarkdownPosts = async (
|
||||
section: SectionKey,
|
||||
limit: number,
|
||||
offset: number
|
||||
): Promise<Post[]> => {
|
||||
let posts: Record<string, () => Promise<unknown>>;
|
||||
switch (section) {
|
||||
case 'poetry':
|
||||
posts = import.meta.glob('/src/posts/poetry/*.md');
|
||||
break;
|
||||
case 'projects':
|
||||
posts = import.meta.glob('/src/routes/(app)/projects/posts/*.md');
|
||||
break;
|
||||
case 'thoughts':
|
||||
posts = import.meta.glob('/src/routes/(app)/thoughts/posts/*.md');
|
||||
break;
|
||||
default:
|
||||
throw new Error('Could not find this section');
|
||||
}
|
||||
const iterablePostFiles = Object.entries(posts);
|
||||
|
||||
const allPosts = await Promise.all(
|
||||
iterablePostFiles.map(async ([path, resolver]) => {
|
||||
const data = await resolver();
|
||||
if (isData(data)) {
|
||||
const { metadata } = data;
|
||||
const postPath = path.slice(11, -3);
|
||||
return {
|
||||
meta: { ...metadata, section: section },
|
||||
path: postPath
|
||||
};
|
||||
} else {
|
||||
throw new Error('Could not properly parse this post');
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const paginatedPosts = allPosts.slice(offset, offset + limit);
|
||||
|
||||
return paginatedPosts;
|
||||
};
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2014-11-10 00:00:00 +0000
|
||||
tags:
|
||||
- Fall
|
||||
title: Autumn Synesthesia
|
||||
|
||||
---
|
||||
The trees branch out their reds and yellows.
|
||||
Their last battle cry before the frost.
|
||||
The further north, the more pronounced
|
||||
As they recall the life they lost.
|
||||
Shouting in color upon deaf ears,
|
||||
Such beauty produced at a deadly cost.
|
||||
|
||||
The reds rage on
|
||||
With blistering hate.
|
||||
"Is there no escape
|
||||
From our inevitable fate?"
|
||||
|
||||
The orange reminisce
|
||||
On the seasons before.
|
||||
"Winter is knocking,
|
||||
But Spring is next door."
|
||||
|
||||
The yellows enjoy
|
||||
The weather while it lasts.
|
||||
"Best to live in the present
|
||||
Than the future or past."
|
||||
|
||||
The browns mutter softly
|
||||
The last lesson to learn.
|
||||
"From dust I arose,
|
||||
So to dust I return."
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2014-05-20 00:00:00 +0000
|
||||
tags:
|
||||
- Humor
|
||||
- Muffins
|
||||
- Love
|
||||
- Relationships
|
||||
title: Breakfast Blue Pt. 2
|
||||
|
||||
---
|
||||
Oh, my good friend, I didn't mean to leave.
|
||||
It wasn't your fault, so no longer grieve!
|
||||
If I could, I would run back to your side.
|
||||
But, alas, a lack of legs slows my stride.
|
||||
|
||||
It's been over a year since I've last seen
|
||||
Your serious face and Chartwell's cuisine.
|
||||
Often I think this is for the better
|
||||
\'Til I shed tears as I read your letter.
|
||||
|
||||
Fake tears, that is, for I also lack eyes.
|
||||
In fact, let me unveil my disguise:
|
||||
I'm an object lacking animation,
|
||||
Given life through personification.
|
||||
|
||||
What words can I say to help you move on
|
||||
And accept the fact that I am now gone?
|
||||
Know that I too will miss your sweet lovin'
|
||||
For I'll always be your chocolate muffin.
|
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2013-01-10 00:00:00 +0000
|
||||
tags:
|
||||
- Humor
|
||||
- Muffins
|
||||
title: Breakfast Blues
|
||||
|
||||
---
|
||||
Lost my reason to wake in the morning
|
||||
Ever since you left me without warning.
|
||||
We've always seemed to have gotten along
|
||||
Now I'm wondering if I did you wrong.
|
||||
|
||||
Lost my reason to give you thanks and praise.
|
||||
Each day that passes passes in a daze.
|
||||
The life I live is a life of decay.
|
||||
My happiness happens to never stay.
|
||||
|
||||
I would have treated you so much better,
|
||||
Or perhaps branded a scarlet letter
|
||||
Across my chest and openly confess
|
||||
That I'm impressed by a snack I love best.
|
||||
|
||||
Oh chocolate muffin, why'd you have to leave?
|
||||
I've learned not to wear my heart on my sleeve.
|
||||
Instead my love will always be suppressed
|
||||
As I keep it locked in a chocolate chest.
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2019-03-06 12:00:00 +0000
|
||||
tags:
|
||||
- Christian
|
||||
title: Djinn
|
||||
year: 2019
|
||||
---
|
||||
|
||||
"Jesus dropped by."
|
||||
My roommate remarked.
|
||||
"He told me to tell you
|
||||
His phone fell apart."
|
||||
|
||||
I let out a chuckle
|
||||
And a sigh of relief.
|
||||
"He didn't holy ghost us
|
||||
Despite such unbelief."
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2018-04-28 12:00:00 +0000
|
||||
tags:
|
||||
- Wisdom
|
||||
- Lessons
|
||||
title: I've Seen
|
||||
year: 2018
|
||||
|
||||
---
|
||||
I've seen tears fall
|
||||
From the face of a giant,
|
||||
A hint of desperation
|
||||
In the pleas of a king,
|
||||
|
||||
An attempt to forgive
|
||||
The guilt-tripping violent,
|
||||
Their genuine surprise
|
||||
That neither learned a thing.
|
||||
|
||||
The wishes of a mother
|
||||
Remain whispers in the wind,
|
||||
And the riches of the world
|
||||
In the words of humbled men.
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2019-02-02 12:00:00 +0000
|
||||
tags:
|
||||
- Love
|
||||
- Lovers
|
||||
- Relationships
|
||||
- Introspective
|
||||
title: Infrared Homing
|
||||
---
|
||||
|
||||
In a moment
|
||||
Of relapse,
|
||||
A desire
|
||||
For love
|
||||
Arose.
|
||||
|
||||
I gave my heartstrings
|
||||
To a girl
|
||||
To knit a warmer
|
||||
Set of clothes.
|
||||
|
||||
I was hoping
|
||||
For a sweater,
|
||||
But instead,
|
||||
Received her mask.
|
||||
|
||||
She thanked me kindly
|
||||
For the coat
|
||||
And I knew
|
||||
I shouldn't ask.
|
||||
|
||||
Was it
|
||||
Seasonal depression
|
||||
That left me seeking
|
||||
Out a sun?
|
||||
|
||||
A candle
|
||||
Can't replace it,
|
||||
But any fire
|
||||
Is better than none.
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2020-10-01 20:00:00 +0000
|
||||
tags:
|
||||
- Neuroscience
|
||||
- Wisdom
|
||||
title: Judge Judy
|
||||
|
||||
---
|
||||
|
||||
With each passing moment,
|
||||
A court case is held
|
||||
For our mind to determine
|
||||
Which actions to compel.
|
||||
|
||||
86 billion neurons
|
||||
Take up the jury seats
|
||||
And fire off responses
|
||||
'Til a majority agrees.
|
||||
|
||||
"Your Honor, you don't exist,
|
||||
But as an emergent behavior;
|
||||
Yet still we reached a verdict
|
||||
That should work in our favor."
|
||||
|
||||
The neurons are dismissed
|
||||
Then return to jury duty
|
||||
For another microcosm case
|
||||
In their show of Judge Judy.
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2018-06-25 20:00:00 +0000
|
||||
tags:
|
||||
- Chess
|
||||
- Lessons
|
||||
title: King's Pin
|
||||
year: 2018
|
||||
---
|
||||
|
||||
You placed my king
|
||||
In a surprising check
|
||||
To ensure I’m kept
|
||||
On the tip of my toes.
|
||||
|
||||
Only a few
|
||||
Of our pieces are left,
|
||||
And each one of my moves
|
||||
Are presupposed.
|
||||
|
||||
Unbeknownst,
|
||||
Synonymous to beginner.
|
||||
|
||||
A satisfying poach
|
||||
Awarded to the winner.
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2014-10-27 00:00:00 +0000
|
||||
tags:
|
||||
- Humor
|
||||
title: Klepto Couches
|
||||
|
||||
---
|
||||
My home houses countless couches.
|
||||
Klepto-couches with pickpocket pouches
|
||||
That swiftly swipe your cellular phone
|
||||
Between the cushions of their comfy unknown.
|
||||
|
||||
Then your change jingles and jangles
|
||||
Until they're untangled
|
||||
From your Wrangler jeans pocket
|
||||
As you wonder where your socks went.
|
||||
|
||||
But your socks and shoes
|
||||
Were swept under your feet
|
||||
Right under your nose.
|
||||
|
||||
So discreet are these deceitful seats
|
||||
As they watch you search
|
||||
For the keys they stole.
|
||||
|
||||
At last your quest
|
||||
Leads you straight to the crook.
|
||||
"I should have guessed
|
||||
The klepto-couches had took!"
|
||||
|
||||
But still your lesson
|
||||
Has yet to be learned.
|
||||
These klepto-couches
|
||||
Deserve to be burned.
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2012-02-25 00:00:00 +0000
|
||||
tags:
|
||||
- Grounds
|
||||
- Covenant
|
||||
title: Leafblower
|
||||
|
||||
---
|
||||
You're the girl sitting on the park bench.
|
||||
I'm the guy with a leaf blower.
|
||||
I've gotta do my job,
|
||||
So would you kindly please move over?
|
||||
|
||||
I'm walking right towards you,
|
||||
So don't say you didn't notice me.
|
||||
I'd like to get off work soon,
|
||||
So I'll give you until the count of three.
|
||||
|
||||
One
|
||||
Two
|
||||
...
|
||||
|
||||
Alright, so you've called my bluff.
|
||||
I'm not really going to do anything.
|
||||
I just wanted to look real tough,
|
||||
But this little bee ain't got no sting.
|
||||
|
||||
I'll just tell my boss that I missed a spot,
|
||||
And I'll explain my sad situation.
|
||||
Then we'll both laugh at the thought
|
||||
Of me writing poetry about my frustration.
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2019-10-26 12:00:00 +0000
|
||||
tags:
|
||||
- Wisdom
|
||||
title: Of Molecules And Men
|
||||
---
|
||||
|
||||
May we lose
|
||||
All language
|
||||
That we may see
|
||||
As it is
|
||||
And not
|
||||
As we think,
|
||||
|
||||
For cells
|
||||
Arose
|
||||
From division
|
||||
To divide
|
||||
And conquer
|
||||
Molecules
|
||||
And men.
|
||||
|
||||
From the
|
||||
Prokaryote
|
||||
To the
|
||||
Proletariat
|
||||
A conflict
|
||||
Ensues.
|
||||
|
||||
You're so sure
|
||||
That you're full
|
||||
Of yourself
|
||||
As your cells
|
||||
Dismantle
|
||||
All that's
|
||||
Consumed.
|
||||
|
||||
We break to build
|
||||
Each building block
|
||||
Into a likeness
|
||||
Worth worshipping to.
|
||||
|
||||
To be at peace
|
||||
Is to decompose.
|
||||
|
||||
To cease to be
|
||||
Is to become
|
||||
Every friend
|
||||
And alleged foe.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2012-03-01 00:00:00 +0000
|
||||
tags:
|
||||
- Grounds
|
||||
- Covenant
|
||||
title: Monday Morning Shift
|
||||
|
||||
---
|
||||
These plants look beautiful, but not at this location.
|
||||
They must be eradicated according to administration.
|
||||
I brought out my tools; Some gloves and a spade,
|
||||
Then sat down, Indian style, to begin the raid.
|
||||
The roots, like little fingers, held on to dear life
|
||||
As I cut through their homes with an oddly-shaped knife.
|
||||
|
||||
To justify these cruel killings
|
||||
I thought of what they've done:
|
||||
Suffocated the superior plants
|
||||
And blocked out the lovely sun.
|
||||
|
||||
But what makes one plant superior and the other inferior?
|
||||
Just the fact that the other has a beautiful exterior?
|
||||
They are simply trying their best to make a living.
|
||||
We must see past our differences and be more forgiving.
|
||||
|
||||
But these thoughts lead down to a dangerous road;
|
||||
Let's not personify each seed we've sowed.
|
||||
|
||||
The sun now rises and heats the ground.
|
||||
The ice embedded within melts all around,
|
||||
And now a nice wet spot on my pants is found
|
||||
Which leaves me thinking of thoughts more profound:
|
||||
"I really hope no one's looking at me right now."
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2016-05-10 00:00:00 +0000
|
||||
tags:
|
||||
- Work
|
||||
- Worry
|
||||
- Self-conscious
|
||||
title: Morning Commute
|
||||
|
||||
---
|
||||
|
||||
A few minutes into my morning commute
|
||||
I had forgotten we can all read minds.
|
||||
So my thought faucet ran up my brain bill
|
||||
Spewing a membraneous mess inside.
|
||||
|
||||
I didn’t notice ‘til I parked the car
|
||||
And smelled the fumes from under the hood.
|
||||
I frantically thought of cats and cookies
|
||||
To clean up the mess, but it did no good.
|
||||
|
||||
So I ditched the car and snuck into work,
|
||||
Though I knew my hopes and dreams would be seen
|
||||
Swirled amidst my self-doubt and worries
|
||||
Like creamer mixed in bitter cups of caffeine.
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2015-07-15 00:00:00 +0000
|
||||
tags:
|
||||
- Relationships
|
||||
- Love
|
||||
- Drinking
|
||||
- Humor
|
||||
title: Perfect Situation
|
||||
|
||||
---
|
||||
|
||||
When I'm hammered,
|
||||
I'm left enamored
|
||||
And content
|
||||
With the Fate
|
||||
Lady luck's prescribed.
|
||||
|
||||
Though we never
|
||||
Will land together,
|
||||
We're fledglings
|
||||
With new wings
|
||||
To take to the sky.
|
||||
|
||||
I ponder your passion
|
||||
To pursue aspirations
|
||||
And wonder what magic
|
||||
You'll perform upon nations
|
||||
|
||||
And I speculate the odds
|
||||
Given a perfect situation
|
||||
In a parallel universe
|
||||
If I'd rise to the occasion.
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2016-12-20 00:00:00 +0000
|
||||
tags:
|
||||
- Introspective
|
||||
- Silence
|
||||
title: Silent Silas
|
||||
|
||||
---
|
||||
|
||||
The windows to my soul
|
||||
Tend to have their blinds up,
|
||||
And I leave the door locked tight
|
||||
By keeping my own mouth shut
|
||||
|
||||
So my apologies if it's frustrating
|
||||
That I'm so cold and calculating.
|
||||
|
||||
It's my modus operandi;
|
||||
You can't spell "Silent" without Si.
|
||||
|
||||
But if it's any consolation,
|
||||
I am striving to get better
|
||||
At voicing my own thoughts
|
||||
Without resorting to writing letters.
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2014-07-20 00:00:00 +0000
|
||||
tags:
|
||||
- Love
|
||||
- Relationships
|
||||
- Realtalk
|
||||
title: Thought Experiment
|
||||
|
||||
---
|
||||
|
||||
Love is a free fall
|
||||
And I'm afraid of the ground.
|
||||
If I jump and no one's there,
|
||||
Will my body make a sound?
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2017-10-10 00:00:00 +0000
|
||||
tags:
|
||||
- Wisdom
|
||||
- Speech
|
||||
- Verbal Abuse
|
||||
title: Unintentional Internalization
|
||||
|
||||
---
|
||||
|
||||
Our skin's as thick
|
||||
As our words are sharp
|
||||
To dampen the damage
|
||||
We take to heart.
|
||||
|
||||
But sometimes they pierce
|
||||
Right through our defenses,
|
||||
Despite whether the offender
|
||||
Had the best of intentions.
|
||||
|
||||
It's a wound that lingers
|
||||
And leads to a scar
|
||||
Once committed to memory
|
||||
(Which shapes who you are).
|
||||
|
||||
For each one we've endured,
|
||||
We've dealt so many more
|
||||
For the most innocuous remark
|
||||
Still can pierce like a sword.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
categories:
|
||||
- Poetry
|
||||
date: 2013-05-10 00:00:00 +0000
|
||||
tags:
|
||||
- Realtalk
|
||||
title: Who Am I?
|
||||
|
||||
---
|
||||
Am I the clothes on my back
|
||||
And the hair on my head?
|
||||
Am I the people I'm with
|
||||
And the words I've said?
|
||||
|
||||
Am I the field I study
|
||||
And the school I attend?
|
||||
Am I the programs I write
|
||||
And the poems I've penned?
|
||||
|
||||
Am I the music I enjoy
|
||||
And the guitar I play?
|
||||
Am I the grade on my test
|
||||
And my ten page essay?
|
||||
|
||||
Am I the habits I've formed
|
||||
And the phrases I repeat?
|
||||
Am I the fake smile given
|
||||
To every person I meet?
|
||||
|
||||
Am I the religion I follow
|
||||
And the politician I elect?
|
||||
Am I every action I carry out
|
||||
And every thought I reflect?
|
|
@ -0,0 +1,7 @@
|
|||
<script lang="ts">
|
||||
import App from '$lib/components/scenes/app/App.svelte';
|
||||
</script>
|
||||
|
||||
<App>
|
||||
<slot />
|
||||
</App>
|
|
@ -0,0 +1,23 @@
|
|||
<script lang="ts">
|
||||
import MenuItem from '$lib/components/scenes/app/MenuItem.svelte';
|
||||
</script>
|
||||
|
||||
<MenuItem position={[-2.5, 7.5, 0]} htmlContent="Poetry" href="/poetry" />
|
||||
|
||||
<MenuItem
|
||||
position={[2.5, 2.5, -2.5]}
|
||||
htmlContent="Projects"
|
||||
clickHandler={() => console.log('clicked!')}
|
||||
/>
|
||||
|
||||
<MenuItem
|
||||
position={[-2.5, -2.5, -2.5]}
|
||||
htmlContent="Thoughts"
|
||||
clickHandler={() => console.log('clicked!')}
|
||||
/>
|
||||
|
||||
<MenuItem
|
||||
position={[2.5, -7.5, 2.5]}
|
||||
htmlContent="About"
|
||||
clickHandler={() => console.log('clicked!')}
|
||||
/>
|
|
@ -0,0 +1,39 @@
|
|||
<script lang="ts">
|
||||
import MenuItem from '$lib/components/scenes/app/MenuItem.svelte';
|
||||
import type { PageData } from './$types';
|
||||
export let data: PageData;
|
||||
|
||||
const xMin = -2.5,
|
||||
xMax = 2.5;
|
||||
const yMin = -7.5,
|
||||
yMax = 7.5;
|
||||
const zMin = -2.5,
|
||||
zMax = 2.5;
|
||||
|
||||
// Calculate positions
|
||||
const calculatePositions = (numPosts: number): Array<[number, number, number]> => {
|
||||
const positions: Array<[number, number, number]> = [];
|
||||
const numRows = Math.ceil(Math.sqrt(numPosts));
|
||||
const numCols = Math.ceil(numPosts / numRows);
|
||||
|
||||
for (let i = 0; i < numPosts; i++) {
|
||||
const row = Math.floor(i / numCols);
|
||||
const col = i % numCols;
|
||||
|
||||
const x = xMin + (xMax - xMin) * (col / (numCols - 1));
|
||||
const y = yMin + (yMax - yMin) * (row / (numRows - 1));
|
||||
const z = zMin;
|
||||
|
||||
positions.push([x, y, z]);
|
||||
}
|
||||
|
||||
return positions;
|
||||
};
|
||||
|
||||
// Generate positions based on the number of posts
|
||||
const positions = calculatePositions(data.posts.length);
|
||||
</script>
|
||||
|
||||
{#each data.posts as post, i}
|
||||
<MenuItem position={positions[i]} htmlContent={post.meta.title} href={post.path} />
|
||||
{/each}
|
|
@ -0,0 +1,8 @@
|
|||
export const load = async ({ fetch }) => {
|
||||
const response = await fetch(`/api/poetry?limit=5&offset=0`);
|
||||
const posts = await response.json();
|
||||
|
||||
return {
|
||||
posts
|
||||
};
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
<script lang="ts">
|
||||
import MenuItem from '$lib/components/scenes/app/MenuItem.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import DomPortal from '$lib/utils/DomPortal.svelte';
|
||||
export let data: PageData;
|
||||
|
||||
const { title, date: _date, Content, categories: _ } = data;
|
||||
</script>
|
||||
|
||||
<MenuItem position={[-2.5, 10, 0]} htmlContent="Back" href="/poetry" />
|
||||
|
||||
<DomPortal target="#overlay">
|
||||
<div class="py-4">
|
||||
<h1 class="text-xl font-medium text-black pb-2">{title}</h1>
|
||||
<div>
|
||||
<Content />
|
||||
</div>
|
||||
</div>
|
||||
</DomPortal>
|
|
@ -0,0 +1,18 @@
|
|||
import type { Metadata } from '$lib/utils/index.js';
|
||||
|
||||
export async function load({ params }) {
|
||||
const post = await import(`../../../../posts/poetry/${params.slug}.md`);
|
||||
const { title, date, categories } = post.metadata as Metadata;
|
||||
const Content = post.default;
|
||||
const parsedDate = new Date(date.slice(0, date.length - 6));
|
||||
const validDate = `${
|
||||
parsedDate.getMonth() + 1
|
||||
}/${parsedDate.getDate()}/${parsedDate.getFullYear()}`;
|
||||
|
||||
return {
|
||||
Content,
|
||||
title,
|
||||
date: validDate,
|
||||
categories
|
||||
};
|
||||
}
|
|
@ -1,5 +1,38 @@
|
|||
<script>
|
||||
import "../app.css";
|
||||
<script lang="ts">
|
||||
import CanvasContainer from '$lib/components/scenes/app/CanvasContainer.svelte';
|
||||
import '../app.css';
|
||||
</script>
|
||||
|
||||
<slot />
|
||||
<CanvasContainer>
|
||||
<slot />
|
||||
</CanvasContainer>
|
||||
|
||||
<div class="overlay container" id="overlay"></div>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgb(0, 36, 6);
|
||||
background: linear-gradient(180deg, rgba(0, 36, 6, 1) 0%, rgba(0, 0, 0, 1) 100%);
|
||||
position: absolute;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgba(16, 56, 30, 0.9);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
<script lang="ts">
|
||||
import Home from '$lib/components/scenes/home/Home.svelte';
|
||||
import type { PageData } from './$types';
|
||||
export let data: PageData;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#each data.models as model}
|
||||
<span>{model.title}</span>
|
||||
{/each}
|
||||
<Home />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgb(0, 36, 6);
|
||||
background: linear-gradient(180deg, rgba(0, 36, 6, 1) 0%, rgba(0, 0, 0, 1) 100%);
|
||||
display: absolute;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
|
@ -1,15 +0,0 @@
|
|||
const models: Model[] = [
|
||||
{ title: 'Model 1' },
|
||||
{ title: 'Model 2' },
|
||||
{ title: 'Model 3' }
|
||||
];
|
||||
|
||||
export type Model = { title: string}
|
||||
|
||||
export function load(): { models: Model[] } {
|
||||
return {
|
||||
models: models.map((model) => ({
|
||||
title: model.title
|
||||
}))
|
||||
};
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { fetchMarkdownPosts } from '$lib/utils';
|
||||
import { json } from '@sveltejs/kit';
|
||||
|
||||
export const GET = async ({ url }) => {
|
||||
const limit = Number(url.searchParams.get('limit')) || 6;
|
||||
const offset = Number(url.searchParams.get('offset')) || 0;
|
||||
const allPosts = await fetchMarkdownPosts('poetry', limit, offset);
|
||||
|
||||
const sortedPosts = allPosts.sort((a, b) => {
|
||||
return new Date(b.meta.date).getTime() - new Date(a.meta.date).getTime();
|
||||
});
|
||||
|
||||
return json(sortedPosts);
|
||||
};
|
|
@ -1,18 +1,20 @@
|
|||
import adapter from '@sveltejs/adapter-auto';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
import { mdsvex } from 'mdsvex';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
preprocess: [vitePreprocess(), mdsvex({ extensions: ['.md'] })],
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||
adapter: adapter()
|
||||
}
|
||||
},
|
||||
extensions: ['.svelte', '.md']
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
Loading…
Reference in New Issue