replace manual -> work navigating via window with goto()

This commit is contained in:
saiminh 2026-01-23 12:10:56 +13:00
parent d49773134f
commit e277b33bd8
5 changed files with 51 additions and 42 deletions

View file

@ -6,12 +6,19 @@
import { beforeNavigate } from '$app/navigation';
import { browser } from '$app/environment';
import type { Snippet } from 'svelte';
import { onMount } from 'svelte';
interface LayoutData {
pathname: string;
}
let { data, children }: { data: LayoutData; children: Snippet } = $props();
onMount(() => {
console.log('layout mounted');
// Set initial random background color on first load
// setRandomBgColor();
});
let { children }: { children: Snippet } = $props();
let showLoader = $state(false);
let timer: ReturnType<typeof setTimeout> | null = null;
@ -81,7 +88,7 @@
<svelte:head>
<meta property="og:type" content="website" />
<meta property="og:url" content={`https://floter.design`+data.pathname} />
<meta property="og:url" content={`https://floter.design${page.url.pathname}`} />
<meta property="og:image" content="https://floter.design/ogimage.png">
<meta name="twitter:card" content="summary_large_image">
<meta name="description" content={page.data.description ? page.data.description : 'Simon Flöter is a designer and creative developer'} />
@ -89,11 +96,11 @@
</svelte:head>
<Header />
{#key data.pathname}
<!-- {#key data.pathname} -->
<div class="content">
{#if showLoader}
<Loader />
{/if}
{@render children()}
</div>
{/key}
<!-- {/key} -->

View file

@ -1,9 +1,10 @@
import { loading } from '$lib/utils/stores.js'
loading.set(true)
export const load = async ({ url }) => {
const { pathname } = url
loading.set(true)
// Simulate async operation if needed
await new Promise(resolve => setTimeout(resolve, 0))
loading.set(false)
return {
pathname
}
return {}
}

View file

@ -2,6 +2,7 @@
import { onMount } from 'svelte';
import gsap from 'gsap';
import { SplitText } from 'gsap/SplitText';
import { goto } from '$app/navigation';
let { data } = $props();
const orderedPosts = $derived.by(() => (data.posts || []).sort((a, b) => {
@ -53,7 +54,8 @@
workclone.style.top = `0`;
workclone.style.left = `0`;
document.body.appendChild(workclone);
window.location.href = href || ''
// window.location.href = href || ''
goto(href || '');
}
})
gsap.fromTo(split.chars, {

View file

@ -1,7 +1,21 @@
export async function load( { params }: { params: { slug: string }} ){
try {
const post = await import(`../md/${params.slug}.md`)
const { title = '', date = '', header_bg_image = '', svg = '', video = '', tags = [], reference = '', referenceName = '', tasks = [], description = [], images = [], agency = '', agencyName = '' } = post.metadata
const {
title = '',
date = '',
header_bg_image = '',
svg = '',
video = '',
tags = [],
reference = '',
referenceName = '',
tasks = [],
description = [],
images = [],
agency = '',
agencyName = ''
} = post.metadata
// Don't pass the component - it's not serializable
// Import it directly in the page component instead

View file

@ -5,25 +5,9 @@
import { CldImage } from 'svelte-cloudinary';
let { data } = $props();
let visible = $state(false);
let Content = $state<any>(null);
// Import the markdown component dynamically and set up animations
onMount(() => {
// Load the markdown component asynchronously
(async () => {
try {
const post = await import(`../md/${data.slug}.md`);
Content = post.default;
} catch (error) {
console.error('Error loading markdown component:', error);
}
})();
gsap.registerPlugin(ScrollToPlugin);
visible = true;
onMount(() => {
let is_landscape = window.matchMedia('(orientation:landscape)').matches
window.addEventListener('resize', () => {
@ -61,13 +45,13 @@
duration: .5,
ease: 'power2.out',
})
gsap.from('.work', {
y: '100vh',
gsap.to('.work', {
y: '-100vh',
duration: 1,
ease: 'power4.out',
})
gsap.from('.gallery-wrapper', {
y: '-100vh',
gsap.to('.gallery-wrapper', {
y: '100vh',
duration: 1,
ease: 'power4.out',
})
@ -140,8 +124,7 @@
</div>
<div class="gallery-wrapper">
<div class="gallery">
{#if visible}
{#each data.images as image}
{#each data.images as image (image)}
<figure>
{#if image.includes('/video/')}
<video src={image} width="1400" height="840" autoplay muted loop></video>
@ -159,11 +142,9 @@
{/if}
</figure>
{/each}
{/if}
</div>
</div>
<article class="work">
{#if visible}
<div class="description">
{data.description}
</div>
@ -173,7 +154,7 @@
<div class="tasks">
<div class="tasks-title">What I did:</div>
<ul>
{#each data.tags as tag }
{#each data.tags as tag (tag)}
<li>{tag}</li>
{/each}
</ul>
@ -190,12 +171,13 @@
{/if}
</div>
<div class="work-content-text">
{#if Content}
{#await import(`../md/${data.slug}.md`) then { default: Content }}
<Content />
{/if}
{:catch error}
<p>Error loading content: {error.message}</p>
{/await}
</div>
</div>
{/if}
</article>
<style lang="scss">
@ -237,6 +219,8 @@
height: 100%;
}
.work {
position: relative;
top: 100vh;
overflow: hidden;
padding: 0 var(--spacing-outer) 100px var(--spacing-outer);
@media screen and (min-width: 768px) {
@ -324,6 +308,7 @@
}
.gallery-wrapper {
position: relative;
top: -100vh;
width: 100vw;
overflow: hidden;
padding: 0 0 1em 0;
@ -333,7 +318,7 @@
@media screen and (min-width: 768px) {
margin-bottom: -80px;
top: -80px;
top: calc(-100vh - 80px);
padding: 2em 0 4em 0;
margin-bottom: -120px;
perspective: 500px;