Create Memes

Create Memes

/* Complete self-contained CSS */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: Arial, sans-serif; } body { background: #f0f0f0; padding: 20px; } .meme-container { max-width: 900px; margin: 0 auto; background: white; border-radius: 10px; box-shadow: 0 0 20px rgba(0,0,0,0.1); overflow: hidden; } /* Header */ .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; text-align: center; } .header h1 { margin: 0; font-size: 24px; } /* Main Content */ .main-content { display: flex; flex-wrap: wrap; padding: 20px; gap: 20px; } @media (max-width: 768px) { .main-content { flex-direction: column; } } /* Canvas Section */ .canvas-section { flex: 1; min-width: 300px; } .canvas-container { background: #f8f8f8; border: 2px dashed #ddd; border-radius: 8px; padding: 20px; text-align: center; margin-bottom: 20px; } #meme-canvas { width: 100%; max-width: 400px; height: 400px; background: white; display: block; margin: 0 auto; } .upload-area { background: white; border: 2px dashed #ccc; border-radius: 8px; padding: 30px; text-align: center; cursor: pointer; margin-top: 20px; } .upload-area:hover { border-color: #667eea; background: #f5f3ff; } .upload-text { font-size: 18px; color: #666; margin-bottom: 10px; } .upload-subtext { font-size: 14px; color: #999; } /* Controls Section */ .controls-section { flex: 1; min-width: 300px; } .control-group { background: #f8f8f8; border-radius: 8px; padding: 20px; margin-bottom: 20px; } .control-group h3 { margin-bottom: 15px; color: #333; border-bottom: 2px solid #667eea; padding-bottom: 5px; } .control-row { display: flex; align-items: center; margin-bottom: 15px; } .control-label { width: 120px; font-weight: bold; color: #555; } select, input[type=”range”] { flex: 1; padding: 8px; border: 1px solid #ddd; border-radius: 4px; } .color-options { display: flex; gap: 10px; flex-wrap: wrap; } .color-option { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; } .color-option.active { border-color: #333; transform: scale(1.1); } textarea { width: 100%; height: 100px; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; resize: vertical; } /* Buttons */ .buttons { display: flex; gap: 10px; margin-top: 20px; } .btn { padding: 12px 24px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; font-weight: bold; transition: all 0.3s; } .btn-primary { background: #667eea; color: white; flex: 1; } .btn-primary:hover { background: #5a67d8; transform: translateY(-2px); } .btn-secondary { background: #e2e8f0; color: #333; } .btn-secondary:hover { background: #cbd5e0; } /* Footer */ .footer { text-align: center; padding: 20px; color: #666; font-size: 14px; border-top: 1px solid #eee; } /* Modal */ .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000; justify-content: center; align-items: center; } .modal-content { background: white; padding: 30px; border-radius: 10px; max-width: 500px; width: 90%; max-height: 80vh; overflow-y: auto; } .modal h2 { margin-bottom: 20px; color: #333; } .modal-close { position: absolute; top: 10px; right: 10px; background: none; border: none; font-size: 24px; cursor: pointer; color: #666; } /* Toast */ .toast { position: fixed; bottom: 20px; right: 20px; background: #48bb78; color: white; padding: 15px 25px; border-radius: 5px; display: none; z-index: 1001; }
📤 Click to upload image
or drag and drop (JPG, PNG, GIF up to 5MB)

✏️ Text Editor

Text:
Font:
Impact Arial Black Comic Sans Georgia Times New Roman
Color:
Outline:
2px
Size:
36px
// Meme Generator Script – Self-contained (function() { // Initialize when page loads document.addEventListener(‘DOMContentLoaded’, function() { // Get elements const canvas = document.getElementById(‘meme-canvas’); const ctx = canvas.getContext(‘2d’); const textInput = document.getElementById(‘text-input’); const fontSelect = document.getElementById(‘font-select’); const colorOptions = document.querySelectorAll(‘.color-option’); const outlineSlider = document.getElementById(‘outline-slider’); const outlineValue = document.getElementById(‘outline-value’); const sizeSlider = document.getElementById(‘size-slider’); const sizeValue = document.getElementById(‘size-value’); const fileInput = document.getElementById(‘file-input’); const uploadArea = document.getElementById(‘upload-area’); const downloadBtn = document.getElementById(‘download-btn’); const helpBtn = document.getElementById(‘help-btn’); const sampleBtn = document.getElementById(‘sample-btn’); const clearBtn = document.getElementById(‘clear-btn’); const helpModal = document.getElementById(‘help-modal’); const toast = document.getElementById(‘toast’); // State let currentImage = null; let currentText = “TOP TEXT\nBOTTOM TEXT”; let currentFont = “Impact”; let currentColor = “white”; let currentOutline = 2; let currentSize = 36; // Initialize function init() { setupEventListeners(); createSampleImage(); drawMeme(); } // Setup event listeners function setupEventListeners() { // Text input textInput.addEventListener(‘input’, function() { currentText = this.value; drawMeme(); }); // Font selection fontSelect.addEventListener(‘change’, function() { currentFont = this.value; drawMeme(); }); // Color selection colorOptions.forEach(option => { option.addEventListener(‘click’, function() { colorOptions.forEach(opt => opt.classList.remove(‘active’)); this.classList.add(‘active’); currentColor = this.getAttribute(‘data-color’); drawMeme(); }); }); // Outline slider outlineSlider.addEventListener(‘input’, function() { currentOutline = parseInt(this.value); outlineValue.textContent = this.value + ‘px’; drawMeme(); }); // Size slider sizeSlider.addEventListener(‘input’, function() { currentSize = parseInt(this.value); sizeValue.textContent = this.value + ‘px’; drawMeme(); }); // File upload uploadArea.addEventListener(‘click’, function() { fileInput.click(); }); fileInput.addEventListener(‘change’, function(e) { if (e.target.files[0]) { loadImage(e.target.files[0]); } }); // Drag and drop uploadArea.addEventListener(‘dragover’, function(e) { e.preventDefault(); this.style.borderColor = ‘#667eea’; this.style.background = ‘#f5f3ff’; }); uploadArea.addEventListener(‘dragleave’, function() { this.style.borderColor = ‘#ccc’; this.style.background = ‘white’; }); uploadArea.addEventListener(‘drop’, function(e) { e.preventDefault(); this.style.borderColor = ‘#ccc’; this.style.background = ‘white’; if (e.dataTransfer.files[0]) { loadImage(e.dataTransfer.files[0]); } }); // Buttons downloadBtn.addEventListener(‘click’, downloadMeme); helpBtn.addEventListener(‘click’, function() { helpModal.style.display = ‘flex’; }); sampleBtn.addEventListener(‘click’, createSampleImage); clearBtn.addEventListener(‘click’, function() { textInput.value = ”; currentText = ”; drawMeme(); showToast(‘Text cleared!’); }); } // Load image from file function loadImage(file) { // Check file size if (file.size > 5 * 1024 * 1024) { showToast(‘File too large (max 5MB)’, ‘error’); return; } // Check file type if (!file.type.match(‘image.*’)) { showToast(‘Please select an image file’, ‘error’); return; } const reader = new FileReader(); reader.onload = function(e) { const img = new Image(); img.onload = function() { currentImage = img; drawMeme(); showToast(‘Image loaded!’); }; img.src = e.target.result; }; reader.readAsDataURL(file); } // Create sample image function createSampleImage() { // Create a simple gradient image const tempCanvas = document.createElement(‘canvas’); tempCanvas.width = 400; tempCanvas.height = 400; const tempCtx = tempCanvas.getContext(‘2d’); // Draw gradient const gradient = tempCtx.createLinearGradient(0, 0, 400, 400); gradient.addColorStop(0, ‘#667eea’); gradient.addColorStop(1, ‘#764ba2’); tempCtx.fillStyle = gradient; tempCtx.fillRect(0, 0, 400, 400); // Add sample text tempCtx.fillStyle = ‘white’; tempCtx.font = ‘bold 30px Arial’; tempCtx.textAlign = ‘center’; tempCtx.fillText(‘SAMPLE MEME TEMPLATE’, 200, 150); tempCtx.font = ’20px Arial’; tempCtx.fillText(‘Add your own text!’, 200, 200); // Create image from canvas const img = new Image(); img.onload = function() { currentImage = img; drawMeme(); showToast(‘Sample image loaded!’); }; img.src = tempCanvas.toDataURL(); } // Draw the meme function drawMeme() { // Clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw background (white) ctx.fillStyle = ‘white’; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw image if exists if (currentImage) { // Calculate dimensions to fit const scale = Math.min( canvas.width / currentImage.width, canvas.height / currentImage.height ); const width = currentImage.width * scale; const height = currentImage.height * scale; const x = (canvas.width – width) / 2; const y = (canvas.height – height) / 2; ctx.drawImage(currentImage, x, y, width, height); } // Draw text if (currentText) { const lines = currentText.split(‘\n’); const lineHeight = currentSize + 10; const startY = canvas.height / 2 – ((lines.length – 1) * lineHeight) / 2; for (let i = 0; i < lines.length; i++) { if (lines[i].trim()) { drawTextLine(lines[i], canvas.width / 2, startY + (i * lineHeight)); } } } } // Draw a single line of text function drawTextLine(text, x, y) { ctx.font = `bold ${currentSize}px ${currentFont}`; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; // Draw outline ctx.strokeStyle = 'black'; ctx.lineWidth = currentOutline; ctx.lineJoin = 'round'; ctx.strokeText(text, x, y); // Draw fill ctx.fillStyle = currentColor; ctx.fillText(text, x, y); } // Download meme function downloadMeme() { // Create a higher resolution version const tempCanvas = document.createElement('canvas'); tempCanvas.width = 1200; tempCanvas.height = 1200; const tempCtx = tempCanvas.getContext('2d'); // Scale factor const scale = tempCanvas.width / canvas.width; // Draw background tempCtx.fillStyle = 'white'; tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height); // Draw image if (currentImage) { const imgScale = Math.min( tempCanvas.width / currentImage.width, tempCanvas.height / currentImage.height ); const width = currentImage.width * imgScale; const height = currentImage.height * imgScale; const x = (tempCanvas.width – width) / 2; const y = (tempCanvas.height – height) / 2; tempCtx.drawImage(currentImage, x, y, width, height); } // Draw text (scaled) if (currentText) { const lines = currentText.split('\n'); const scaledSize = currentSize * scale; const lineHeight = scaledSize + (10 * scale); const startY = tempCanvas.height / 2 – ((lines.length – 1) * lineHeight) / 2; tempCtx.font = `bold ${scaledSize}px ${currentFont}`; tempCtx.textAlign = 'center'; tempCtx.textBaseline = 'middle'; tempCtx.strokeStyle = 'black'; tempCtx.lineWidth = currentOutline * scale; tempCtx.lineJoin = 'round'; tempCtx.fillStyle = currentColor; for (let i = 0; i < lines.length; i++) { if (lines[i].trim()) { const y = startY + (i * lineHeight); tempCtx.strokeText(lines[i], tempCanvas.width / 2, y); tempCtx.fillText(lines[i], tempCanvas.width / 2, y); } } } // Create download link const link = document.createElement('a'); link.download = 'meme-' + Date.now() + '.png'; link.href = tempCanvas.toDataURL('image/png'); // Trigger download document.body.appendChild(link); link.click(); document.body.removeChild(link); showToast('Meme downloaded!'); } // Show toast message function showToast(message, type = 'success') { toast.textContent = message; toast.style.display = 'block'; toast.style.background = type === 'error' ? '#f56565' : '#48bb78'; setTimeout(function() { toast.style.display = 'none'; }, 3000); } // Global functions for modal window.closeModal = function() { helpModal.style.display = 'none'; }; // Close modal when clicking outside helpModal.addEventListener('click', function(e) { if (e.target === helpModal) { closeModal(); } }); // Initialize the app init(); }); })();

www.themoneymakingexpert.academy