diff --git a/public/images/about/aurora1.jpg b/public/images/about/aurora1.jpg new file mode 100644 index 0000000..b1763a9 Binary files /dev/null and b/public/images/about/aurora1.jpg differ diff --git a/public/images/about/beach1.jpg b/public/images/about/beach1.jpg new file mode 100644 index 0000000..8394bf9 Binary files /dev/null and b/public/images/about/beach1.jpg differ diff --git a/public/images/about/dapperSasha.jpg b/public/images/about/dapperSasha.jpg index 67d6e31..4abd2f7 100644 Binary files a/public/images/about/dapperSasha.jpg and b/public/images/about/dapperSasha.jpg differ diff --git a/public/images/about/family1.jpg b/public/images/about/family1.jpg new file mode 100644 index 0000000..26b8f7a Binary files /dev/null and b/public/images/about/family1.jpg differ diff --git a/public/images/about/family2.jpg b/public/images/about/family2.jpg new file mode 100644 index 0000000..dfaa19a Binary files /dev/null and b/public/images/about/family2.jpg differ diff --git a/public/images/about/friend2.jpg b/public/images/about/friend2.jpg new file mode 100644 index 0000000..f8ba5b0 Binary files /dev/null and b/public/images/about/friend2.jpg differ diff --git a/public/images/about/gamecube.jpg b/public/images/about/gamecube.jpg index 499ea68..5166c1e 100644 Binary files a/public/images/about/gamecube.jpg and b/public/images/about/gamecube.jpg differ diff --git a/public/images/about/girl1.jpg b/public/images/about/girl1.jpg new file mode 100644 index 0000000..3615511 Binary files /dev/null and b/public/images/about/girl1.jpg differ diff --git a/public/images/about/kitty.mp4 b/public/images/about/kitty.mp4 new file mode 100644 index 0000000..f88aed5 Binary files /dev/null and b/public/images/about/kitty.mp4 differ diff --git a/public/images/about/melfort1.jpg b/public/images/about/melfort1.jpg new file mode 100644 index 0000000..ce65bbf Binary files /dev/null and b/public/images/about/melfort1.jpg differ diff --git a/public/images/about/melfort2.jpg b/public/images/about/melfort2.jpg new file mode 100644 index 0000000..69493ff Binary files /dev/null and b/public/images/about/melfort2.jpg differ diff --git a/public/images/about/melfort3.png b/public/images/about/melfort3.png new file mode 100644 index 0000000..bfc3049 Binary files /dev/null and b/public/images/about/melfort3.png differ diff --git a/public/images/about/melfort4.jpg b/public/images/about/melfort4.jpg new file mode 100644 index 0000000..80af67a Binary files /dev/null and b/public/images/about/melfort4.jpg differ diff --git a/public/images/about/melfort5.jpg b/public/images/about/melfort5.jpg new file mode 100644 index 0000000..a072cbd Binary files /dev/null and b/public/images/about/melfort5.jpg differ diff --git a/public/images/about/outdoor1.jpg b/public/images/about/outdoor1.jpg new file mode 100644 index 0000000..74695c3 Binary files /dev/null and b/public/images/about/outdoor1.jpg differ diff --git a/public/images/about/outdoor2.jpg b/public/images/about/outdoor2.jpg new file mode 100644 index 0000000..0e92e28 Binary files /dev/null and b/public/images/about/outdoor2.jpg differ diff --git a/public/images/about/pcBuild.jpg b/public/images/about/pcBuild.jpg new file mode 100644 index 0000000..db44581 Binary files /dev/null and b/public/images/about/pcBuild.jpg differ diff --git a/public/images/about/slab.jpg b/public/images/about/slab.jpg new file mode 100644 index 0000000..057bad3 Binary files /dev/null and b/public/images/about/slab.jpg differ diff --git a/public/images/about/snowboard1.mp4 b/public/images/about/snowboard1.mp4 new file mode 100644 index 0000000..24480a0 Binary files /dev/null and b/public/images/about/snowboard1.mp4 differ diff --git a/public/images/about/snowboard2.mp4 b/public/images/about/snowboard2.mp4 new file mode 100644 index 0000000..cec7903 Binary files /dev/null and b/public/images/about/snowboard2.mp4 differ diff --git a/public/images/about/steak.jpg b/public/images/about/steak.jpg index 2cac2c8..1bfe45f 100644 Binary files a/public/images/about/steak.jpg and b/public/images/about/steak.jpg differ diff --git a/src/components/BentoGrid.tsx b/src/components/BentoGrid.tsx index 2750a8a..c0b6f98 100644 --- a/src/components/BentoGrid.tsx +++ b/src/components/BentoGrid.tsx @@ -8,39 +8,42 @@ interface BentoItem { description: string; className?: string; // For sizing: bento-large, bento-wide, bento-tall bgImage: string | string[]; + videoSrc?: string; // Optional video source } const items: BentoItem[] = [ { id: 'gaming', - title: "Gaming & Tech", - description: "Wind down with some PC gaming or just appreciating good new gear.", + title: "Gaming", + description: "From Old Classic Fighting Game Tournaments to New PC Gaming Experiences. I enjoy it all", className: "bento-large", - bgImage: "https://placehold.co/800x800/2a1a4a/FFF?text=Gaming+Setup" + bgImage: "/images/about/slab.jpg" }, { id: 'snowboarding', title: "Snowboarding", - description: "The rush of going down the mountains are unmatched", + description: "Here is me teaching my girlfriend😅", className: "bento-tall", - bgImage: "https://placehold.co/400x800/a7ffeb/004d40?text=Snowboarding" + bgImage: "https://placehold.co/400x800/a7ffeb/004d40?text=Snowboarding", + videoSrc: "/images/about/snowboard2.mp4" }, { id: 'cooking', - title: "Culinary Arts", - description: "Experimenting with new recipes and flavors in the kitchen.", - className: "", // Standard 1x1 - bgImage: "https://placehold.co/400x400/3e2723/d7ccc8?text=Cooking" + title: "Cooking", + description: "Everyone cooks sure, I'll give you that. But I want to master the art of cooking a excellent steak.", + className: "", + bgImage: "/images/about/steak.jpg" }, { id: 'social', title: "Family & Friends", description: "Good times with my favorite people. Including my Girlfriend, Friends and Family", - className: "", // Standard 1x1 + className: "bento-tall", bgImage: [ - "https://placehold.co/400x400/f8bbd0/880e4f?text=Social+1", - "https://placehold.co/400x400/d81b60/ffffff?text=Social+2", - "https://placehold.co/400x400/880e4f/f8bbd0?text=Social+3" + "/images/about/girl1.jpg", + "/images/about/family1.jpg", + "/images/about/family2.jpg", + "/images/about/friend2.jpg", ] }, { @@ -49,6 +52,59 @@ const items: BentoItem[] = [ description: "I enjoy the challenge of self-hosting my own digital services at home. I also love tinkering with new hardware and software setups.", className: "bento-wide", bgImage: "/images/projects/homelabber.png" + }, + { + id: 'controller-modding', + title: "Controller Modding", + description: "Restoring and modifying retro game controllers. Giving new life to old hardware.", + className: "", // Standard 1x1 + bgImage: "/images/about/gamecube.jpg" + }, + { + id: 'outdoor-exploring', + title: "Outdoor Exploring", + description: "Hiking mountains, exploring caves, beaches and more.", + className: "bento-tall", + bgImage: [ + "/images/about/outdoor1.jpg", + "/images/about/outdoor2.jpg", + "/images/about/beach1.jpg", + ] + }, + { + id: 'smart-home', + title: "Smart Home", + description: "Automating my living space with smart devices and custom integrations.", + className: "", // Standard 1x1 + bgImage: "https://placehold.co/400x400/0288d1/e1f5fe?text=Smart+Home" + }, + { + id: 'pc-building', + title: "Computer Building", + description: "Designing and assembling custom PC builds for performance and aesthetics.", + className: "bento-wide", + bgImage: "/images/about/pcBuild.jpg" + }, + { + id: 'small-town', + title: "Small Town Origin", + description: "I'm from Melfort, Saskatchewan. A small town with a big heart.", + className: "", // Standard 1x1 + bgImage: [ + "/images/about/melfort1.jpg", + "/images/about/melfort2.jpg", + "/images/about/melfort3.png", + "/images/about/melfort4.jpg", + "/images/about/melfort5.jpg", + ] + }, + { + id: 'cats', + title: "Cats", + description: "I see a cat, I pet a cat. Simple as that.", + className: "bento-large", + bgImage: "https://placehold.co/800x800/ffccbc/bf360c?text=Cats", // Fallback + videoSrc: "/images/about/kitty.mp4" } ]; @@ -71,21 +127,33 @@ const BentoCard = ({ item, index, delay }: { item: BentoItem; index: number; del animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5, delay: delay + index * 0.1 }} > - - { - e.currentTarget.src = "https://placehold.co/600x400?text=" + item.title; - }} + style={{ objectFit: 'cover', opacity: 0.6 }} /> - + ) : ( + + { + e.currentTarget.src = "https://placehold.co/600x400?text=" + item.title; + }} + /> + + )}

{item.title}

diff --git a/src/components/ParticlesBackground.tsx b/src/components/ParticlesBackground.tsx index f1ba7d1..6d1cbc7 100644 --- a/src/components/ParticlesBackground.tsx +++ b/src/components/ParticlesBackground.tsx @@ -79,6 +79,7 @@ const ParticlesBackground: React.FC = () => { // Mobile (390x844) -> ~48 particles // Mobile Landscape (844x390) -> ~48 particles (Same as portrait!) const area = canvas.width * canvas.height; + // Reduce density further to specificially help the heavy About page const particleCount = Math.floor(Math.sqrt(area) / 12); particles = []; @@ -90,17 +91,7 @@ const ParticlesBackground: React.FC = () => { const animate = () => { if (!ctx || !canvas) return; ctx.clearRect(0, 0, canvas.width, canvas.height); - // Draw a subtle gradient background for the canvas itself if needed, or keep transparent - // For now, let's keep it transparent so we can style the container behind it if we want, - // OR we can make this the definitive background. - // Let's add a deep gradient here to match the user's previous aesthetic but cooler. - const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height); - gradient.addColorStop(0, '#0f0c29'); - gradient.addColorStop(0.5, '#302b63'); - gradient.addColorStop(1, '#24243e'); - ctx.fillStyle = gradient; - ctx.fillRect(0, 0, canvas.width, canvas.height); - + // Gradient is now handled by CSS to avoid repainting every frame particles.forEach((particle) => { particle.update(); @@ -119,18 +110,38 @@ const ParticlesBackground: React.FC = () => { for (let b = a; b < particles.length; b++) { const dx = particles[a].x - particles[b].x; const dy = particles[a].y - particles[b].y; - const distance = Math.sqrt(dx * dx + dy * dy); + + // Optimization 1: Strictly check max possible visible distance + // The opacity formula becomes <= 0 when distance > (2/3 * distanceThreshold). + // Max distanceThreshold is 300, so max visible distance is 200. + if (Math.abs(dx) > 200 || Math.abs(dy) > 200) continue; + + const distSq = dx * dx + dy * dy; + const sizeAverage = (particles[a].size + particles[b].size) / 2; // Scale from 100 to 300 based on size average (2 to 6) const distanceThreshold = 100 + (sizeAverage - 2) * 50; - if (distance < distanceThreshold) { - ctx.strokeStyle = `rgba(255, 255, 255, ${(distanceThreshold * (2 / 3) * .001) - distance / 1000})`; - ctx.lineWidth = sizeAverage; - ctx.beginPath(); - ctx.moveTo(particles[a].x, particles[a].y); - ctx.lineTo(particles[b].x, particles[b].y); - ctx.stroke(); + // Optimization 2: Only calculate if we are within the VISIBLE threshold (2/3 of logical threshold) + // Opacity = (Threshold * 2/3 * 0.001) - (dist / 1000) + // 0 = (2/3 T)/1000 - d/1000 => d = 2/3 T + const distinctThreshold = distanceThreshold * (2 / 3); + const distinctThresholdSq = distinctThreshold * distinctThreshold; + + if (distSq < distinctThresholdSq) { + const distance = Math.sqrt(distSq); + + // Calculate opacity + const opacity = (distanceThreshold * (2 / 3) * .001) - distance / 1000; + + if (opacity > 0) { + ctx.strokeStyle = `rgba(255, 255, 255, ${opacity})`; + ctx.lineWidth = sizeAverage; + ctx.beginPath(); + ctx.moveTo(particles[a].x, particles[a].y); + ctx.lineTo(particles[b].x, particles[b].y); + ctx.stroke(); + } } } } @@ -166,6 +177,7 @@ const ParticlesBackground: React.FC = () => { width: '100%', height: '120vh', // Extend well below viewport to cover mobile browser bar retraction zIndex: -1, // Behind everything + background: 'linear-gradient(to bottom, #0f0c29 0%, #302b63 50%, #24243e 100%)' }} /> ); diff --git a/src/pages/About.tsx b/src/pages/About.tsx index f436cee..9537938 100644 --- a/src/pages/About.tsx +++ b/src/pages/About.tsx @@ -34,7 +34,7 @@ export default function About() { transition={{ duration: 0.8 }} >
- About Me - + */} -

Personal Interests