Compare commits

...

7 Commits
main ... main

15 changed files with 246 additions and 77 deletions

13
docker-compose.yml Normal file
View File

@ -0,0 +1,13 @@
services:
nodejs:
image: node:latest
container_name: node_app
working_dir: /app
volumes:
- ./:/app
ports:
- "80:5173"
command: >
sh -c "npm i -g npm@latest &&
npm i &&
npm run dev"

View File

@ -4,7 +4,7 @@
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"dev": "vite dev --host",
"build": "vite build",
"preview": "vite preview",
"format": "prettier --write .",

View File

@ -0,0 +1,9 @@
<script>
import Header from "$lib/components/Common/Content/Heading.svelte";
</script>
<div class="w-max h-1/2 m-auto flex flex-col">
<Header content="Backwards Development"/>
<p class="max-w-screen-lg">I'm Alexander Harding, I am the Founder of Backwards Development. I created Backwards Development as an umbrella for all of my professional works, this website was designed to allow for distribution for my software, tools and applications!</p>
<p class="max-w-screen-lg">Backwards Development is a group I founded to work on whatever enter's my plate, If you need anything done, feel free to <a href="/#contact" class="text-primary-500 underline">Contact Us</a> at any time!</p>
</div>

View File

@ -0,0 +1,7 @@
<script>
import Heading from "$lib/components/Common/Content/Heading.svelte";
</script>
<div>
<Heading content="Backwards Media"/>
</div>

View File

@ -0,0 +1,5 @@
<script>
export let content;
</script>
<h1 class="h1 text-center pt-4">{content}</h1>

View File

@ -0,0 +1,75 @@
<script>
import { sectionStore } from "$lib/stores/currentSection";
import { onMount } from "svelte";
import { fly, slide } from "svelte/transition";
export let page,
slides,
includeFirst = true;
let newSlides = includeFirst ? slides : slides.slice(1);
let pageSection = sectionStore[page];
let currentSection = $pageSection;
onMount(() => {
pageSection.subscribe((cs) => {
currentSection = cs;
});
});
</script>
{#if includeFirst ? currentSection >= 0 : currentSection > 0}
<div
in:fly={{ x: 50, duration: 300 }}
out:fly={{ x: 50, duration: 300 }}
class="tracker"
>
{#each newSlides as _, i}
<div
class="tracker-dot {(includeFirst ? i : i + 1) ===
currentSection
? 'active'
: ''}"
></div>
{/each}
</div>
{/if}
<style>
/* Tracker Styles */
.tracker {
position: fixed;
top: 50%;
right: 20px;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 10px;
}
.tracker-dot {
width: 10px;
height: 10px;
@apply bg-surface-600;
border-radius: 50%;
transition: background-color 0.3s ease;
}
.tracker-dot.active {
@apply bg-primary-600;
}
@media (prefers-color-scheme: light) {
.tracker-dot {
@apply bg-surface-300;
border-radius: 50%;
transition: background-color 0.3s ease;
}
.tracker-dot.active {
@apply bg-primary-600;
}
}
</style>

View File

@ -4,7 +4,7 @@
</script>
<div class="w-screen h-screen flex justify-center items-center">
<form action="?/contact" class="bg-surface-900 w-1/2 h-1/2 p-8 rounded-md">
<form action="?/contact" class="bg-surface-200 dark:bg-surface-900 w-1/2 h-max p-8 rounded-md">
<h1 class="h1 font-bold ps-4 pb-4">Contact Us</h1>
<hr class="opacity-25" />
<p class="pt-4">Fullname</p>

View File

@ -1,5 +1,5 @@
<script>
import Hero from "$lib/components/Hero.svelte";
import Hero from "$lib/components/Main/Hero.svelte";
import ArrowDown from "~icons/material-symbols/keyboard-double-arrow-down-rounded";
import { crossfade, fade, fly } from "svelte/transition";
import { onMount } from "svelte";

View File

@ -0,0 +1,6 @@
import { writable } from "svelte/store";
export let sectionStore = {
about: writable(),
main: writable()
};

View File

@ -1,92 +1,85 @@
<script>
import { onMount } from "svelte";
import Header from "$lib/components/Header.svelte";
import Downloads from "$lib/components/Downloads.svelte";
import { fly } from "svelte/transition";
import Media from "$lib/components/Media.svelte";
import Contact from "$lib/components/Contact.svelte";
import TechStack from "$lib/components/TechStack.svelte";
import { onMount } from "svelte";
import Header from "$lib/components/Main/Header.svelte";
import Downloads from "$lib/components/Main/Downloads.svelte";
import { fly, slide } from "svelte/transition";
import Media from "$lib/components/Main/Media.svelte";
import Contact from "$lib/components/Main/Contact.svelte";
import TechStack from "$lib/components/Main/TechStack.svelte";
import Tracker from "$lib/components/Common/Tracker.svelte";
import { sectionStore } from "$lib/stores/currentSection";
/* IMPORTANT */
// Anything added into the page directly will likely break the page's scrolling behaviour
// To properly add something to the main page, make it into a component and add it to the array.
// This array is in order of how they are to be displayed, modifying their positions will modify them in page.
/* IMPORTANT */
// Anything added into the page directly will likely break the page's scrolling behaviour
// To properly add something to the main page, make it into a component and add it to the array.
// This array is in order of how they are to be displayed, modifying their positions will modify them in page.
let slides = [
Header,
Downloads,
Media,
TechStack,
Contact
];
let slides = [Header, Downloads, Media, TechStack, Contact];
let { main } = sectionStore;
let currentSection = 0;
if (!$main) main.set(0);
// Update the current section based on scroll position
const handleScroll = () => {
const sections = document.querySelectorAll(".section");
const scrollTop = document.querySelector(".scroll-container").scrollTop;
sections.forEach((section, index) => {
if (section.offsetTop <= scrollTop + window.innerHeight / 2) {
currentSection = index;
}
});
};
let currentSection = $main;
// Update the current section based on scroll position
const handleScroll = () => {
const sections = document.querySelectorAll(".section");
const scrollTop = document.querySelector(".scroll-container").scrollTop;
sections.forEach((section, index) => {
if (section.offsetTop <= scrollTop + window.innerHeight / 2) {
main.set(index);
}
});
};
</script>
<div id="main" class="scroll-container" on:scroll={handleScroll}>
{#each slides as content}
<section class="section">
<svelte:component this={content} />
</section>
{/each}
{#each slides as content}
<section class="section">
<svelte:component this={content} />
</section>
{/each}
</div>
<!-- Tracker -->
{#if currentSection > 0}
<div in:fly={{ x: 50, duration: 300 }} out:fly={{ x: 50, duration: 300 }} class="tracker">
{#each slides.slice(1) as _, i}
<div class="tracker-dot {i + 1 === currentSection ? 'active' : ''}"></div>
{/each}
</div>
{/if}
<Tracker page="main" {slides} includeFirst={false} />
<style>
.scroll-container {
scroll-snap-type: y mandatory;
overflow-y: auto;
height: 100vh;
width: 100vw;
scroll-behavior: smooth;
}
.scroll-container {
scroll-snap-type: y mandatory;
overflow-y: auto;
height: 100vh;
width: 100vw;
scroll-behavior: smooth;
}
.section {
scroll-snap-align: start;
min-height: 100vh; /* Full viewport height */
width: 100vw;
}
.section {
scroll-snap-align: start;
min-height: 100vh; /* Full viewport height */
width: 100vw;
}
/* Tracker Styles */
.tracker {
position: fixed;
top: 50%;
right: 20px;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 10px;
}
/* Tracker Styles */
.tracker {
position: fixed;
top: 50%;
right: 20px;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 10px;
}
.tracker-dot {
width: 10px;
height: 10px;
@apply bg-surface-600;
border-radius: 50%;
transition: background-color 0.3s ease;
}
.tracker-dot {
width: 10px;
height: 10px;
@apply bg-surface-600;
border-radius: 50%;
transition: background-color 0.3s ease;
}
.tracker-dot.active {
@apply bg-primary-600;
}
.tracker-dot.active {
@apply bg-primary-600;
}
</style>

View File

@ -0,0 +1,61 @@
<script>
import Me from '$lib/components/About/Me.svelte';
import Media from '$lib/components/About/Media.svelte';
import Tracker from '$lib/components/Common/Tracker.svelte';
import { sectionStore } from '$lib/stores/currentSection';
import { onMount } from 'svelte';
/* IMPORTANT */
// Anything added into the page directly will likely break the page's scrolling behaviour
// To properly add something to the main page, make it into a component and add it to the array.
// This array is in order of how they are to be displayed, modifying their positions will modify them in page.
let slides = [
Me,
Media
];
let { about } = sectionStore
if (!$about) about.set(0);
let currentSection = $about;
// Update the current section based on scroll position
const handleScroll = () => {
const sections = document.querySelectorAll('.section');
const scrollTop = document.querySelector('.scroll-container').scrollTop;
sections.forEach((section, index) => {
if (section.offsetTop <= scrollTop + window.innerHeight / 2) {
about.set(index);
}
});
};
</script>
<div id="main" class="scroll-container" on:scroll={handleScroll}>
{#each slides as content}
<section class="section flex flex-row">
<svelte:component this={content} />
</section>
{/each}
</div>
<!-- Tracker -->
<Tracker page="about" slides={slides} />
<style>
.scroll-container {
scroll-snap-type: y mandatory;
overflow-y: auto;
height: 100vh;
width: 100vw;
scroll-behavior: smooth;
}
.section {
scroll-snap-align: start;
min-height: 100vh; /* Full viewport height */
width: 100vw;
}
</style>