From 2646321ad9879547f40026828ebfc21e2468098a Mon Sep 17 00:00:00 2001 From: John Gatward Date: Thu, 19 Mar 2026 16:08:39 +0000 Subject: [PATCH] Enhance projects --- index.html | 301 +++++++++++++++++++++++++++++++---------------------- script.js | 27 +++++ style.css | 68 ++++++++++++ 3 files changed, 274 insertions(+), 122 deletions(-) diff --git a/index.html b/index.html index 8d80ad1..d033319 100644 --- a/index.html +++ b/index.html @@ -20,7 +20,6 @@ @@ -176,8 +175,8 @@ a console output.

- React.js - TypeScript + React + TypeScript HTML/CSS
@@ -217,137 +216,197 @@

projects

Things I built

- Recent projects & things I found interesting. I have gone to painstaking lengths to not edit my older - projects... we all start somewhere. + A timeline of all my projects and experiments. Started with p5.js, then the tech-stack mirrored whatever I was interested in at that time.

-
- - 14 Nov 2024 - Thin Ice - A small tile game created inspired by a childhood game. +
+ Featured projects +
+ +
- -
+
+ All projects +
- -
- -

Things I wrote down

-

- Best way to learn is to teach. When I find something interesting I write a short tutorial — mainly to - consolidate my own understanding, but if it helps someone else that's a win. -

-

- Had to really try my best to not touch anything here. Every tutorial here is exacty how it was when I wrote - it in sixth form. -

+
+ + + + + + + + +
-
- - 3 Jan 2021 - Summed-area tables - Counting cells in a summed-area table, investigating how they work and why - they're efficient. +
+ + 14 Nov 2024 + Thin Ice + A small browser tile game inspired by one I played growing up. + + C++ + WebAssembly + RayLib + - - 3 Feb 2019 - Midpoint displacement terrain generation - Generating random, natural-looking 2D terrains using the midpoint displacement - algorithm. + + 20 Mar 2024 + Travelling Salesman Problem + A nearest-neighbor + 2-opt pathfinding visualiser. + + Zig + WebGL + WebAssembly + - - 14 Feb 2018 - Convex hull generator - Wrapping algorithms — visualising how to find the convex hull of a point - set. + + 31 Jan 2024 + Flocking + A simulation to show how complex behaviour emerges from 3 simple rules. + + Rust + Raylib + - - 22 Sept 2018 - Travelling Salesperson Problem - Different implementations of the TSP problem — a classic. + + 1 Nov 2023 + samstoreymusic.com + A website design and build for a friend working in music. + + HTML/CSS + JavaScript + + + + + 21 Jul 2023 + Game of Life + After building Conway's Game of Life in p5.js, I expanded it into a generic automata simulator. + + React + JavaScript + + + + + 5 Feb 2022 + Percolation + A visual demo of percolation through a medium, showing how behavior changes as p increases. + + C + RayLib + WebAssembly + + + + + 1 Oct 2021 + Drawing Bézier curves + An interactive diagram for cubic Bézier curves. + + JavaScript + p5.js + + + + + 17 Sep 2021 + 2D Marching Squares + Basic map rendering. + + JavaScript + p5.js + + + + + 2 Apr 2020 + Müller-Lyer illusion + A JavaScript visualisation of the Müller-Lyer optical illusion. + + JavaScript + p5.js + + + + + 27 Feb 2019 + Fourier series + Builds a square wave from sine components to show Fourier series in motion. + + JavaScript + p5.js + + + + + 23 Feb 2019 + Constructing an ellipse + Shows how an ellipse can be constructed from a circle and radial lines, inspired by 3Blue1Brown. + + JavaScript + p5.js + + + + + 18 Mar 2018 + Calculating PI + Approximates pi using the Monte Carlo method with random points in a square and circle. + + JavaScript + p5.js + + + + + 17 Dec 2017 + Oscillations in 3D + A JavaScript recreation of a Bees and Bombs animation. + + JavaScript + p5.js + + + + + 13 Nov 2017 + Maze generator + A p5.js maze generator using depth-first search and recursive backtracking. + + JavaScript + p5.js +
@@ -396,12 +455,10 @@ diff --git a/script.js b/script.js index 981bfa2..813906f 100644 --- a/script.js +++ b/script.js @@ -22,3 +22,30 @@ window.addEventListener('scroll', () => { a.style.color = a.getAttribute('href') === `#${current}` ? 'var(--mauve)' : ''; }); }); + +// ─── Project filters ────────────────────────────────────────────── +const filterChips = document.querySelectorAll('.filter-chip'); +const projectCards = document.querySelectorAll('#project-grid .project-card'); + +if (filterChips.length > 0 && projectCards.length > 0) { + const applyFilter = (filter) => { + projectCards.forEach(card => { + const tech = (card.dataset.tech || '').split(/\s+/).filter(Boolean); + const shouldShow = filter === 'all' || tech.includes(filter); + card.classList.toggle('is-hidden', !shouldShow); + }); + }; + + filterChips.forEach(chip => { + chip.addEventListener('click', () => { + const selected = chip.dataset.filter || 'all'; + + filterChips.forEach(other => { + other.classList.toggle('active', other === chip); + }); + + applyFilter(selected); + }); + }); +} + diff --git a/style.css b/style.css index 44f7321..427c2e7 100644 --- a/style.css +++ b/style.css @@ -515,6 +515,8 @@ section.full-width { .tag-mauve { background: rgba(203,166,247,0.12); color: var(--mauve); } .tag-yellow { background: rgba(249,226,175,0.12); color: var(--yellow); } .tag-sky { background: rgba(137,220,235,0.12); color: var(--sky); } +.tag-red { background: rgba(243,139,168,0.12); color: var(--red); } +.tag-pink { background: rgba(245,194,231,0.12); color: var(--pink); } /* ─── Tutorials / Projects shared ─────────────────────── */ .section-heading { @@ -535,6 +537,71 @@ section.full-width { margin-bottom: 3rem; } +.projects-subheading { + margin: 0 0 0.9rem; + font-size: 0.7rem; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--mauve); +} + +.card-grid.card-grid--featured { + margin-bottom: 2rem; + grid-template-columns: repeat(2, minmax(0, 1fr)); +} + +#projects .section-intro { + margin-bottom: 1.8rem; + max-width: 640px; +} + +#project-grid { + grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); +} + +#project-grid .card { + padding: 1.2rem; +} + +.project-filters { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + border: none; + padding: 0; + min-width: 0; + margin-bottom: 1.25rem; +} + +.filter-chip { + border: 1px solid var(--surface1); + background: var(--mantle); + color: var(--subtext0); + border-radius: 999px; + padding: 0.32rem 0.8rem; + font-size: 0.68rem; + letter-spacing: 0.04em; + text-transform: uppercase; + font-family: 'JetBrains Mono', monospace; + cursor: pointer; + transition: all 0.2s; +} + +.filter-chip:hover { + border-color: var(--mauve); + color: var(--text); +} + +.filter-chip.active { + background: rgba(203,166,247,0.18); + border-color: rgba(203,166,247,0.7); + color: var(--mauve); +} + +.card.is-hidden { + display: none; +} + /* ─── Card grid ────────────────────────────────────────── */ .card-grid { display: grid; @@ -725,6 +792,7 @@ footer a:hover { color: var(--mauve); } nav { padding: 0 1.5rem; } .nav-links { gap: 1.2rem; } section { padding: 6rem 1.5rem 4rem; } + .card-grid.card-grid--featured { grid-template-columns: 1fr; } .about-columns { grid-template-columns: 1fr; } .about-block-tag { width: 4rem; } .skills-grid { grid-template-columns: 1fr; }