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
26 changes: 26 additions & 0 deletions Meme Generator/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Meme Generator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Meme Generator</h1>
<div>
<textarea id="top-text"></textarea>
Text size: <input type="range" id="top-text-size-input" min="0.05" max="0.25" value="0.15" step="0.01">
</div>
<textarea id="bottom-text"></textarea>
Text size: <input type="range" id="bottom-text-size-input" min="0.05" max="0.25" value="0.15" step="0.01">
</div>
<div>
<input type="file" id="image-input" accept="image/*">
</div>
<div>
<button id="generate-btn">Generate!</button>
</div>
<canvas id="meme-canvas" title="Right click to save this meme"></canvas>
<script src="script.js"></script>
</body>
</html>
69 changes: 69 additions & 0 deletions Meme Generator/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
function generateMeme(img, topText, bottomText, topTextSize, bottomTextSize) {
const canvas = document.getElementById('meme-canvas');
const ctx = canvas.getContext('2d');

// Size canvas to image
canvas.width = img.width;
canvas.height = img.height;

// Clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw main image
ctx.drawImage(img, 0, 0);

// Text style: white with black borders
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.textAlign = 'center';

// Top text font size
let fontSize = canvas.width * topTextSize;
ctx.font = `${fontSize}px Impact`;
ctx.lineWidth = fontSize / 20;

// Draw top text
ctx.textBaseline = 'top';
topText.split('\n').forEach((t, i) => {
ctx.fillText(t, canvas.width / 2, i * fontSize, canvas.width);
ctx.strokeText(t, canvas.width / 2, i * fontSize, canvas.width);
});

// Bottom text font size
fontSize = canvas.width * bottomTextSize;
ctx.font = `${fontSize}px Impact`;
ctx.lineWidth = fontSize / 20;

// Draw bottom text
ctx.textBaseline = 'bottom';
bottomText.split('\n').reverse().forEach((t, i) => { // .reverse() because it's drawing the bottom text from the bottom up
ctx.fillText(t, canvas.width / 2, canvas.height - i * fontSize, canvas.width);
ctx.strokeText(t, canvas.width / 2, canvas.height - i * fontSize, canvas.width);
});
}

window.addEventListener('DOMContentLoaded', (event) => {
// Initialize variables
const topTextInput = document.getElementById('top-text');
const bottomTextInput = document.getElementById('bottom-text');
const topTextSizeInput = document.getElementById('top-text-size-input');
const bottomTextSizeInput = document.getElementById('bottom-text-size-input');
const imageInput = document.getElementById('image-input');
const generateBtn = document.getElementById('generate-btn');
// Default/Demo text
topTextInput.value = 'Top\nValue';
bottomTextInput.value = 'Bottom\nValue';

// Generate button click listener
generateBtn.addEventListener('click', () => {
// Read image as DataURL using the FileReader API
const reader = new FileReader();
reader.onload = () => {
const img = new Image;
img.src = reader.result;
img.onload = () => {
generateMeme(img, topTextInput.value, bottomTextInput.value,topTextSizeInput.value, bottomTextSizeInput.value);
};
};
reader.readAsDataURL(imageInput.files[0]);
});
});
18 changes: 18 additions & 0 deletions Meme Generator/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
h1 {
font-family: Impact, 'Arial Narrow Bold', sans-serif;
font-size: 30px;
}

body{
margin: 10px;
background-color: lightblue;


}
p {
font-family: "sans-serif";
}

#meme-canvas {
width: 300px;
}