Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions public/MemeGenerator/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Meme Generator</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css" />
<script src="script.js" defer></script>
</head>
<body>
<div class="container">
<h1>Meme Generator</h1>
<button class="generate-button">🎉 Generate Meme</button>
<div class="meme-container">
<h2 class="meme-title">Loading...</h2>
<img class="meme-image" alt="Meme Image">
<p class="author"></p>
</div>
</div>
</body>
</html>
32 changes: 32 additions & 0 deletions public/MemeGenerator/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const generateBtn = document.querySelector('.generate-button');
const memeTitle = document.querySelector('.meme-title');
const memeImage = document.querySelector('.meme-image');
const authorOutput = document.querySelector('.author');

function getMeme() {
// Add "Loading..." effect
memeTitle.innerText = "Loading...";
memeImage.src = "";
authorOutput.innerText = "";

fetch('https://meme-api.com/gimme/wholesomememes')
.then((res) => res.json())
.then((data) => {
const { author, title, url } = data;
memeTitle.innerText = title;
memeImage.src = url;
authorOutput.innerText = `Meme by: ${author}`;
})
.catch((err) => {
memeTitle.innerText = "Oops! Something went wrong 😅";
console.error(err);
});
}

// Initial meme
getMeme();

// Button click
generateBtn.addEventListener('click', () => {
getMeme();
});
105 changes: 105 additions & 0 deletions public/MemeGenerator/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
* {
box-sizing: border-box;
}

body {
margin: 0;
font-family: 'Nunito', sans-serif;
text-align: center;
background: linear-gradient(to right, #74ebd5, #ACB6E5);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}

.container {
width: 100%;
max-width: 500px;
padding: 20px;
}

/* Heading */
h1 {
color: #2c3e50;
margin-bottom: 20px;
}

/* Button */
.generate-button {
border: none;
font: inherit;
padding: 14px 20px;
background: linear-gradient(to right, #ff6b6b, #f06595);
color: white;
width: 100%;
border-radius: 10px;
cursor: pointer;
font-size: 18px;
transition: all 0.3s ease;
box-shadow: 0px 5px 15px rgba(0,0,0,0.2);
margin-bottom: 20px;
}

.generate-button:hover {
transform: scale(1.05);
box-shadow: 0px 8px 20px rgba(0,0,0,0.3);
}

.generate-button:active {
transform: scale(0.98);
}

/* Meme Card */
.meme-container {
background-color: #ffffffcc;
padding: 20px;
border-radius: 15px;
box-shadow: 0 8px 25px rgba(0,0,0,0.2);
transition: all 0.3s ease;
}

.meme-container:hover {
transform: translateY(-5px);
box-shadow: 0 12px 30px rgba(0,0,0,0.3);
}

/* Meme title */
.meme-title {
margin: 0;
font-size: 22px;
color: #2c3e50;
min-height: 30px;
transition: all 0.3s ease;
}

/* Meme image */
.meme-image {
width: 100%;
border-radius: 12px;
margin: 12px 0;
transition: all 0.3s ease;
}

/* Hide image if not loaded */
.meme-image:not([src]) {
display: none;
}

/* Author text */
.author {
margin: 0;
font-size: 14px;
color: #34495e;
}

/* Responsive */
@media (max-width: 500px) {
.generate-button {
font-size: 16px;
padding: 12px 18px;
}
.meme-title {
font-size: 20px;
}
}
16 changes: 16 additions & 0 deletions scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1780,6 +1780,22 @@ class WebDev100Days {
"Custom styled cards with profile photos and reviews"
]
},
{
originalDay: 170,
name: "Meme Generator",
description: "A fun web app that fetches and displays wholesome memes from an API. Users can generate a new meme at the click of a button, complete with title, image, and author info.",
demoLink: "./public/MemeGenerator/index.html",
category: "projects",
technologies: ["HTML", "CSS", "JavaScript", "Fetch API"],
features: [
"Fetches memes from the 'wholesomememes' subreddit via API",
"Displays meme title, image, and author dynamically",
"Loading effect while fetching a new meme",
"Click button to generate a new random meme",
"Responsive design with hover and shadow effects",
"Smooth transitions for image and text changes"
]
},

];

Expand Down