Meme Generator Project Complete 😮💨
This commit is contained in:
@@ -2,20 +2,82 @@
|
||||
|
||||
## Description
|
||||
|
||||
A brief description of the meme generator project.
|
||||
The Meme Generator project is a web-based application that allows users to create their own memes. Users can upload images or provide image URLs, add custom text to the top and bottom of the image, adjust text size, and export the final meme as a PNG file.
|
||||
|
||||
## Features
|
||||
|
||||
- Feature 1
|
||||
- Feature 2
|
||||
- Feature 3
|
||||
- **Image Upload**: Upload an image from your local system.
|
||||
- **Image URL**: Use an image from the web by providing its URL.
|
||||
- **Custom Text**: Add and edit custom text at the top and bottom of the image.
|
||||
- **Text Styling**: Adjust the font size of the text.
|
||||
- **Export Meme**: Export the created meme as a PNG file.
|
||||
|
||||
## Technologies Used
|
||||
|
||||
- JavaScript
|
||||
- HTML
|
||||
- CSS
|
||||
- **JavaScript**: Core logic for handling image upload, text rendering, and exporting the meme.
|
||||
- **HTML**: Structure of the application.
|
||||
- **CSS**: Styling for the application.
|
||||
|
||||
## Setup
|
||||
|
||||
Instructions to set up and run the project.
|
||||
Follow these steps to set up and run the project locally:
|
||||
|
||||
1. **Clone the repository**:
|
||||
```sh
|
||||
git clone https://github.com/deepakkumar55/ULTIMATE-JAVASCRIPT-PROJECT.git
|
||||
cd Fun%20and%20Creative%20Projects/2-meme_generator/
|
||||
```
|
||||
|
||||
2. **Open the project**:
|
||||
Open the `index.html` file in your preferred web browser.
|
||||
|
||||
3. **Start Creating Memes**:
|
||||
- Upload an image or provide an image URL.
|
||||
- Add custom text to the top and bottom of the image.
|
||||
- Adjust the text size as needed.
|
||||
- Export your meme as a PNG file.
|
||||
|
||||
## Contribution
|
||||
|
||||
Contributions are welcome! If you have any ideas for improvements or new features, please follow these steps:
|
||||
|
||||
1. **Fork the repository**:
|
||||
Click the "Fork" button on the top right of the repository page.
|
||||
|
||||
2. **Clone your forked repository**:
|
||||
```sh
|
||||
git clone https://github.com/deepakkumar55/ULTIMATE-JAVASCRIPT-PROJECT.git
|
||||
cd Fun%20and%20Creative%20Projects/2-meme_generator/
|
||||
```
|
||||
|
||||
3. **Create a new branch**:
|
||||
```sh
|
||||
git checkout -b feature-or-bugfix-name
|
||||
```
|
||||
|
||||
4. **Make your changes**:
|
||||
Implement your feature or fix the bug.
|
||||
|
||||
5. **Commit your changes**:
|
||||
```sh
|
||||
git add .
|
||||
git commit -m "Description of your changes"
|
||||
```
|
||||
|
||||
6. **Push to your forked repository**:
|
||||
```sh
|
||||
git push origin feature-or-bugfix-name
|
||||
```
|
||||
|
||||
7. **Create a pull request**:
|
||||
Go to the original repository and click on the "New Pull Request" button. Provide a detailed description of your changes and submit the pull request.
|
||||
|
||||
---
|
||||
|
||||
## Get in Touch
|
||||
|
||||
If you have any questions or need further assistance, feel free to open an issue on GitHub or contact us directly. Your contributions and feedback are highly appreciated!
|
||||
|
||||
---
|
||||
|
||||
Thank you for your interest in Notes app project. Together, we can build a more robust and feature-rich application. Happy coding!
|
||||
|
||||
59
Fun and Creative Projects/2-meme_generator/index.html
Normal file
59
Fun and Creative Projects/2-meme_generator/index.html
Normal file
@@ -0,0 +1,59 @@
|
||||
<!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="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>Meme Generator</h1>
|
||||
<button id="export">Export</button>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="memeForm">
|
||||
<div class="box">
|
||||
<div>
|
||||
<label for="imgURL">Image URL:</label>
|
||||
<input type="text" id="imgURL" placeholder="Enter Url Of Image" class="input">
|
||||
</div>
|
||||
<div>
|
||||
<label for="imgFile">Upload Image:</label>
|
||||
<input type="file" id="imgFile" class="input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>
|
||||
<label for="textTop">Top Text:</label>
|
||||
<input type="text" id="textTop" placeholder="Enter Top Text" class="input">
|
||||
</div>
|
||||
<div>
|
||||
<label for="textBottom">Bottom Text:</label>
|
||||
<input type="text" id="textBottom" placeholder="Enter Bottom Text" class="input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="sliderContainer">
|
||||
<label for="textSizeTop">Top Text Size:</label>
|
||||
<input type="range" id="textSizeTop" min="10" max="100" value="10">
|
||||
<span id="textSizeTopOut">10</span>
|
||||
</div>
|
||||
<div class="sliderContainer">
|
||||
<label for="textSizeBottom">Bottom Text Size:</label>
|
||||
<input type="range" id="textSizeBottom" min="10" max="100" value="10">
|
||||
<span id="textSizeBottomOut">10</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div>
|
||||
<input type="checkbox" id="trueSize">
|
||||
<label for="trueSize">True Size</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="canvasWrapper"></div>
|
||||
</div>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
169
Fun and Creative Projects/2-meme_generator/script.js
Normal file
169
Fun and Creative Projects/2-meme_generator/script.js
Normal file
@@ -0,0 +1,169 @@
|
||||
(function (window, document) {
|
||||
CanvasRenderingContext2D.prototype.drawBreakingText = function (str, x, y, w, lh, method) {
|
||||
var textSize = parseInt(this.font.replace(/\D/gi, ''));
|
||||
var textParts = [];
|
||||
var textPartsNo = 0;
|
||||
var words = [];
|
||||
var currLine = '';
|
||||
var testLine = '';
|
||||
str = str || '';
|
||||
x = x || 0;
|
||||
y = y || 0;
|
||||
w = w || this.canvas.width;
|
||||
lh = lh || 1;
|
||||
method = method || 'fill';
|
||||
|
||||
textParts = str.split('\n');
|
||||
textPartsNo = textParts.length;
|
||||
|
||||
for (var i = 0; i < textParts.length; i++) {
|
||||
words[i] = textParts[i].split(' ');
|
||||
}
|
||||
|
||||
textParts = [];
|
||||
|
||||
for (var i = 0; i < textPartsNo; i++) {
|
||||
currLine = '';
|
||||
for (var j = 0; j < words[i].length; j++) {
|
||||
testLine = currLine + words[i][j] + ' ';
|
||||
if (this.measureText(testLine).width > w && j > 0) {
|
||||
textParts.push(currLine);
|
||||
currLine = words[i][j] + ' ';
|
||||
} else {
|
||||
currLine = testLine;
|
||||
}
|
||||
}
|
||||
textParts.push(currLine);
|
||||
}
|
||||
|
||||
for (var i = 0; i < textParts.length; i++) {
|
||||
if (method === 'fill') {
|
||||
this.fillText(textParts[i].trim(), x, y + (textSize * lh * i));
|
||||
} else if (method === 'stroke') {
|
||||
this.strokeText(textParts[i].trim(), x, y + (textSize * lh * i));
|
||||
} else if (method === 'none') {
|
||||
return { 'textParts': textParts, 'textHeight': textSize * lh * textParts.length };
|
||||
} else {
|
||||
console.warn('drawBreakingText: ' + method + 'Text() does not exist');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return { 'textParts': textParts, 'textHeight': textSize * lh * textParts.length };
|
||||
};
|
||||
})(window, document);
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
var canvasWrapper = document.getElementById('canvasWrapper');
|
||||
canvasWrapper.appendChild(canvas);
|
||||
canvas.width = 500;
|
||||
canvas.height = 500;
|
||||
var ctx = canvas.getContext('2d');
|
||||
var padding = 15;
|
||||
var textTop = 'I use coding torque to learn';
|
||||
var textBottom = 'web development by creating projects';
|
||||
var textSizeTop = 10;
|
||||
var textSizeBottom = 10;
|
||||
var image = new Image();
|
||||
|
||||
// Setting the crossOrigin attribute
|
||||
image.crossOrigin = "Anonymous";
|
||||
|
||||
image.onload = function () {
|
||||
resetCanvas();
|
||||
draw();
|
||||
};
|
||||
|
||||
document.getElementById('imgURL').oninput = function () {
|
||||
image.src = this.value;
|
||||
};
|
||||
|
||||
document.getElementById('imgFile').onchange = function () {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
image.src = reader.result;
|
||||
};
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
};
|
||||
|
||||
document.getElementById('textTop').oninput = function () {
|
||||
textTop = this.value;
|
||||
draw();
|
||||
};
|
||||
|
||||
document.getElementById('textBottom').oninput = function () {
|
||||
textBottom = this.value;
|
||||
draw();
|
||||
};
|
||||
|
||||
document.getElementById('textSizeTop').oninput = function () {
|
||||
textSizeTop = parseInt(this.value);
|
||||
draw();
|
||||
document.getElementById('textSizeTopOut').textContent = this.value;
|
||||
};
|
||||
|
||||
document.getElementById('textSizeBottom').oninput = function () {
|
||||
textSizeBottom = parseInt(this.value);
|
||||
draw();
|
||||
document.getElementById('textSizeBottomOut').textContent = this.value;
|
||||
};
|
||||
|
||||
document.getElementById('trueSize').onchange = function () {
|
||||
if (this.checked) {
|
||||
canvas.classList.remove('fullwidth');
|
||||
} else {
|
||||
canvas.classList.add('fullwidth');
|
||||
}
|
||||
};
|
||||
|
||||
document.getElementById('export').onclick = function () {
|
||||
try {
|
||||
var img = canvas.toDataURL('image/png');
|
||||
var link = document.createElement("a");
|
||||
link.download = 'My_Meme.png';
|
||||
link.href = img;
|
||||
link.click();
|
||||
|
||||
var win = window.open('', '_blank');
|
||||
win.document.write('<img style="box-shadow: 0 0 1em 0 dimgrey;" src="' + img + '"/>');
|
||||
win.document.write('<h1 style="font-family: Helvetica; font-weight: 300">Right Click > Save As<h1>');
|
||||
win.document.body.style.padding = '1em';
|
||||
} catch (error) {
|
||||
console.error("Failed to export image: ", error);
|
||||
}
|
||||
};
|
||||
|
||||
function resetCanvas() {
|
||||
canvas.outerHTML = '';
|
||||
canvas = document.createElement('canvas');
|
||||
canvasWrapper.appendChild(canvas);
|
||||
ctx = canvas.getContext('2d');
|
||||
draw();
|
||||
}
|
||||
|
||||
function style(font, size, align, base) {
|
||||
ctx.font = size + 'px ' + font;
|
||||
ctx.textAlign = align;
|
||||
ctx.textBaseline = base;
|
||||
}
|
||||
|
||||
function draw() {
|
||||
canvas.width = image.width;
|
||||
canvas.height = image.height;
|
||||
|
||||
ctx.drawImage(image, 0, 0);
|
||||
|
||||
style('Impact', textSizeTop, 'center', 'top');
|
||||
ctx.lineWidth = textSizeTop / 12;
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.strokeStyle = 'black';
|
||||
ctx.drawBreakingText(textTop, canvas.width / 2, padding, canvas.width - (padding * 2), 1.1, 'stroke');
|
||||
ctx.drawBreakingText(textTop, canvas.width / 2, padding, canvas.width - (padding * 2), 1.1, 'fill');
|
||||
|
||||
style('Impact', textSizeBottom, 'center', 'bottom');
|
||||
ctx.lineWidth = textSizeBottom / 12;
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.strokeStyle = 'black';
|
||||
ctx.drawBreakingText(textBottom, canvas.width / 2, canvas.height - padding, canvas.width - (padding * 2), 1.1, 'stroke');
|
||||
ctx.drawBreakingText(textBottom, canvas.width / 2, canvas.height - padding, canvas.width - (padding * 2), 1.1, 'fill');
|
||||
}
|
||||
195
Fun and Creative Projects/2-meme_generator/styles.css
Normal file
195
Fun and Creative Projects/2-meme_generator/styles.css
Normal file
@@ -0,0 +1,195 @@
|
||||
/* General styling for the body */
|
||||
body {
|
||||
background-color: #1e293b; /* Dark background for better contrast */
|
||||
color: white;
|
||||
font-family: 'Arial', sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Styling for the header */
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
padding: 1rem;
|
||||
background-color: #1B2E3C;
|
||||
border-bottom: 2px solid #3bf6ae;
|
||||
}
|
||||
|
||||
/* Button styling */
|
||||
#export {
|
||||
background: #3b82f6;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 10px 20px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
|
||||
#export:hover {
|
||||
background: #2563eb;
|
||||
}
|
||||
|
||||
/* Container styling */
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
/* Styling for the form container */
|
||||
.memeForm {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
padding: 1rem;
|
||||
background-color: #273244;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* Box styling for form elements */
|
||||
.box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Form element spacing */
|
||||
.box div {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Styling for text input containers */
|
||||
.text_input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
background-color: #353b48;
|
||||
border-radius: 30px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
/* Styling for input fields */
|
||||
.input {
|
||||
flex-grow: 1;
|
||||
color: white;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
background: none;
|
||||
width: 250px;
|
||||
line-height: 30px;
|
||||
transition: width 0.4s linear;
|
||||
padding: 0 10px;
|
||||
border: 1px solid #3b82f6;
|
||||
border-radius: 50px;
|
||||
}
|
||||
|
||||
/* Slider container styling */
|
||||
.sliderContainer {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* Styling for sliders */
|
||||
#textSizeTop,
|
||||
#textSizeBottom {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
height: 18px;
|
||||
width: 100%;
|
||||
border-radius: 10em;
|
||||
background-color: deepskyblue;
|
||||
outline: none;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
/* Slider thumb styling */
|
||||
#textSizeBottom::-webkit-slider-thumb,
|
||||
#textSizeTop::-webkit-slider-thumb,
|
||||
#textSizeBottom::-moz-range-thumb,
|
||||
#textSizeTop::-moz-range-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border-radius: 50%;
|
||||
background: #3b82f6;
|
||||
cursor: pointer;
|
||||
border: 3px solid #f4f4f4;
|
||||
}
|
||||
|
||||
/* Checkbox styling */
|
||||
input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Checkbox label styling */
|
||||
input[type="checkbox"] + label {
|
||||
display: block;
|
||||
position: relative;
|
||||
padding-left: 35px;
|
||||
margin-bottom: 20px;
|
||||
font: 14px/20px "Open Sans", Arial, sans-serif;
|
||||
color: #ddd;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Checkbox label before styling */
|
||||
input[type="checkbox"] + label:before {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid #6cc0e5;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
opacity: 0.6;
|
||||
transition: all 0.12s, border-color 0.08s;
|
||||
}
|
||||
|
||||
/* Checkbox checked state styling */
|
||||
input[type="checkbox"]:checked + label:before {
|
||||
width: 10px;
|
||||
top: -5px;
|
||||
left: 5px;
|
||||
border-radius: 0;
|
||||
opacity: 1;
|
||||
border-top-color: transparent;
|
||||
border-left-color: transparent;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
/* Fullwidth canvas styling */
|
||||
.fullwidth {
|
||||
width: 100%;
|
||||
min-width: 400px;
|
||||
max-height: 800px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* Canvas wrapper styling */
|
||||
#canvasWrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
padding: 1rem;
|
||||
background-color: #1e293b;
|
||||
}
|
||||
Reference in New Issue
Block a user