Skip to content

Commit 1016466

Browse files
committed
New Images and Rubber Ducky Mahem!!!
Updated images. Added some fun stuff on the MyWork section. A div shadows the rubber ducky in the background image. Hovering over it makes a quack sound and launches emoji ducks in the air. Clicking it takes users to the site rubberduckdebugging.com.
1 parent 2ed96b9 commit 1016466

File tree

10 files changed

+111
-10
lines changed

10 files changed

+111
-10
lines changed

package-lock.json

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"react-icons": "^4.12.0",
1919
"react-microsoft-clarity": "^1.2.0",
2020
"react-parallax-tilt": "^1.7.179",
21+
"react-rewards": "^2.0.4",
2122
"react-router-dom": "^6.21.1",
2223
"react-scripts": "^5.0.1",
2324
"react-scroll": "^1.9.0",

src/assets/images/diy.jpeg

-581 KB
Loading

src/assets/images/office.jpeg

601 KB
Loading

src/assets/images/rex.jpeg

-370 KB
Loading

src/assets/sounds/quack.mp3

39.4 KB
Binary file not shown.

src/components/Home/Hobbies.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,25 +22,25 @@ const hobbies = [
2222
image: skiing,
2323
title: "Skiing",
2424
description:
25-
"Skiing: An Infrequent but Thrilling Adventure - When the rare opportunity arises, I hit the slopes with friends, immersing myself in the exhilarating world of skiing. It's more than just a hobby; it's a cherished passion that awakens with every snowy trail and heart-pounding descent. These moments, though few, are always cherished and unforgettable.",
25+
"An Infrequent but Thrilling Adventure - When the rare opportunity arises, I hit the slopes with friends, immersing myself in the exhilarating world of skiing. It's more than just a hobby; it's a cherished passion that awakens with every snowy trail and heart-pounding descent. These moments, though few, are always cherished and unforgettable.",
2626
},
2727
{
2828
image: programming,
2929
title: "Programming",
3030
description:
31-
"Programming: A Creative Outlet - I'm a programmer, and I love it. I'm always on the lookout for new projects and challenges, and I'm constantly learning new skills and languages. It's a creative outlet that allows me to explore new ideas and concepts, and it's a hobby that I'll never get tired of.",
31+
"A Creative Outlet - I'm a programmer, and I love it. I'm always on the lookout for new projects and challenges, and I'm constantly learning new skills and languages. It's a creative outlet that allows me to explore new ideas and concepts, and it's a hobby that I'll never get tired of.",
3232
},
3333
{
3434
image: diy,
3535
title: "DIY",
3636
description:
37-
"DIY: The Art of Creation - I'm a DIYer at heart. I love building things with my hands, and I'm always on the lookout for new projects. Whether it's a new piece of furniture, a new gadget, or building a beautiful deck and pergola as shown above. I'm always looking for a new challenge and new ways to improve my skills.",
37+
"The Art of Creation - I'm a DIYer at heart. I love building things with my hands, and I'm always on the lookout for new projects. Whether it's a new piece of furniture, a new gadget, or building a beautiful deck and pergola as shown above. I'm always looking for a new challenge and new ways to improve my skills.",
3838
},
3939
{
4040
image: rex,
4141
title: "Rex",
4242
description:
43-
"Rex, My Labrador Sidekick: Our hobbies include endless games of fetch that test both our agility and patience, daily walks that are as much about exploration as exercise, and the occasional beach escapade where the sand and waves add to our adventurous spirit. Together, we embrace the simple joys of play and the outdoors.",
43+
"My Labrador Sidekick - Our hobbies include endless games of fetch that test both our agility and patience, daily walks that are as much about exploration as exercise, and the occasional beach escapade where the sand and waves add to our adventurous spirit. Together, we embrace the simple joys of play and the outdoors.",
4444
},
4545
];
4646
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

src/components/Home/MyWork.tsx

+80-6
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
77
// ----- Import the required modules
88

9+
import { useEffect, useRef } from "react";
910
import { Container, Row, Col } from "react-bootstrap";
1011
import GitHubCalendar from "react-github-calendar";
11-
12+
import { useReward } from "react-rewards";
1213
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
13-
// -- Import Icons/Images
14+
// -- Import Icons/Images/Sounds
1415

1516
import { SiTypescript, SiJavascript, SiPython, SiReact, SiPowershell, SiAzurefunctions, SiMicrosoftazure, SiGithub, SiElectron, SiRedis, SiMicrosoftsqlserver } from "react-icons/si";
1617
import { FaNodeJs } from "react-icons/fa";
1718
import { DiGit } from "react-icons/di";
1819
import mojLogo from "../../assets/images/moj.jpeg";
19-
20+
import quackSound from "../../assets/sounds/quack.mp3";
2021
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2122
// -- Define the skills to display
2223

@@ -65,9 +66,82 @@ function GitHubSection() {
6566
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6667
// ----- Define the MyWork component
6768

68-
function index() {
69+
function MyWork() {
70+
const duckRef = useRef<HTMLDivElement>(null);
71+
const sectionRef = useRef<HTMLElement>(null);
72+
73+
// Duck confetti reward
74+
const duckConfettiConfig = {
75+
emoji: ["🦆", "🐤", "🐥"],
76+
elementCount: 60,
77+
spread: 150,
78+
zIndex: 9999,
79+
lifetime: 300,
80+
position: "absolute",
81+
};
82+
83+
// Make 🦆 the dominant emoji
84+
for (let i = 0; i < 25; i++) {
85+
duckConfettiConfig.emoji.push("🦆");
86+
}
87+
const { reward: duckConfetti, isAnimating: ducksInFlight } = useReward("duckConfetti", "emoji", duckConfettiConfig);
88+
89+
const handleDuckMouseOver = () => {
90+
if (!ducksInFlight) {
91+
duckConfetti(); // Launch the ducks!
92+
}
93+
const audio = new Audio(quackSound);
94+
audio.play().catch((error) => {
95+
console.warn("Duck can't quack:", error);
96+
});
97+
};
98+
const handleDuckClick = () => {
99+
window.open("https://rubberduckdebugging.com", "_blank");
100+
};
101+
102+
// Some overkill code to position a div overlay ontop of the rubber ducky in the background image
103+
useEffect(() => {
104+
const duckOriginalPosition = { x: 3114, y: 2180 }; // Coordinates of the duck in the original image
105+
const backgroundOriginalSize = { width: 4032, height: 3024 }; // Size of the original image
106+
107+
// Calculate the position of the overlay and update it
108+
const positionOverlay = () => {
109+
if (!sectionRef.current || !duckRef.current) return;
110+
111+
const containerRect = sectionRef.current.getBoundingClientRect();
112+
const containerAspectRatio = containerRect.width / containerRect.height;
113+
const imageAspectRatio = backgroundOriginalSize.width / backgroundOriginalSize.height;
114+
115+
let scaleFactor;
116+
let offsetX = 0;
117+
let offsetY = 0;
118+
119+
if (containerAspectRatio > imageAspectRatio) {
120+
scaleFactor = containerRect.width / backgroundOriginalSize.width;
121+
offsetY = (containerRect.height - backgroundOriginalSize.height * scaleFactor) / 2;
122+
} else {
123+
scaleFactor = containerRect.height / backgroundOriginalSize.height;
124+
offsetX = (containerRect.width - backgroundOriginalSize.width * scaleFactor) / 2;
125+
}
126+
127+
const newX = duckOriginalPosition.x * scaleFactor + offsetX;
128+
const newY = duckOriginalPosition.y * scaleFactor + offsetY;
129+
130+
duckRef.current.style.left = `${newX}px`;
131+
duckRef.current.style.top = `${newY}px`;
132+
};
133+
134+
window.addEventListener("resize", positionOverlay);
135+
positionOverlay(); // Initial call
136+
137+
return () => {
138+
window.removeEventListener("resize", positionOverlay);
139+
};
140+
}, []);
141+
69142
return (
70-
<section id="mywork" className="mywork-section">
143+
<section id="mywork" className="mywork-section" ref={sectionRef}>
144+
<div id="duckConfetti" className="interactive-duck" ref={duckRef} onMouseOver={handleDuckMouseOver} onClick={handleDuckClick}></div>
71145
<Container className="mywork-description">
72146
<h1 className="main-heading">
73147
My <strong className="primary-color">Work</strong>
@@ -98,4 +172,4 @@ function index() {
98172
);
99173
}
100174

101-
export default index;
175+
export default MyWork;

src/react-app-env.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
/// <reference types="react-scripts" />
2+
declare module "*.mp3" {
3+
const src: string;
4+
export default src;
5+
}

src/styles/Home/MyWork.css

+12
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@
1313
background-position: center center;
1414
background-repeat: no-repeat;
1515
background-size: cover;
16+
overflow: hidden;
17+
}
18+
19+
.interactive-duck {
20+
position: absolute;
21+
width: 100px;
22+
height: 100px;
23+
cursor: pointer;
1624
}
1725

1826
.mywork-description {
@@ -109,4 +117,8 @@
109117
.mywork-mojlogo {
110118
margin-bottom: 10%;
111119
}
120+
121+
.interactive-duck {
122+
visibility: hidden; /* Hide duck element on tablets/phones */
123+
}
112124
}

0 commit comments

Comments
 (0)