From 492b71a220ac722995873223d4e3513c7ff60dd8 Mon Sep 17 00:00:00 2001 From: findirfin <89416531+findirfin@users.noreply.github.com> Date: Fri, 30 Aug 2024 08:48:18 -0600 Subject: [PATCH] updated simple meme workflow and added some better styling --- editor.html | 328 ++++------------------------------------------ editor/script.js | 219 +++++++++++++++++++++++++++++++ editor/styles.css | 153 +++++++++++++++++++++ 3 files changed, 397 insertions(+), 303 deletions(-) create mode 100644 editor/script.js create mode 100644 editor/styles.css diff --git a/editor.html b/editor.html index a6f6d92..ee46337 100644 --- a/editor.html +++ b/editor.html @@ -4,338 +4,60 @@ Advanced Meme Creator - - +

Advanced Meme Creator

+ + +
+ +
- - + + +
- -
+ -
- Meme -
-
-
- - - + + \ No newline at end of file diff --git a/editor/script.js b/editor/script.js new file mode 100644 index 0000000..a6fe813 --- /dev/null +++ b/editor/script.js @@ -0,0 +1,219 @@ +const topTextInput = document.getElementById('topText'); +const bottomTextInput = document.getElementById('bottomText'); +const topTextOutput = document.getElementById('topTextOutput'); +const bottomTextOutput = document.getElementById('bottomTextOutput'); +const createMemeButton = document.getElementById('createMeme'); +const imageFileInput = document.getElementById('imageFile'); +const imageUrlInput = document.getElementById('imageUrl'); +const loadUrlImageButton = document.getElementById('loadUrlImage'); +const memeImage = document.getElementById('memeImage'); +const memeContainer = document.getElementById('memeContainer'); +const memeTypeSelect = document.getElementById('memeType'); +const simpleTextInputs = document.getElementById('simpleTextInputs'); +const customTextContainer = document.getElementById('customTextContainer'); +const customTextInput = customTextContainer.querySelector('input'); +const addTextBtn = customTextContainer.querySelector('button'); +const simpleFont = document.getElementById('simpleFont'); +const customFontSize = document.getElementById('customFontSize'); +const customFont = document.getElementById('customFont'); + +const defaultImageSrc = '/api/placeholder/600/400'; +let isDefaultImage = true; + +function updateSimpleMemeText() { + topTextOutput.textContent = topTextInput.value; + bottomTextOutput.textContent = bottomTextInput.value; + fitTextToContainer(topTextOutput); + fitTextToContainer(bottomTextOutput); +} + +function fitTextToContainer(element) { + const maxWidth = memeImage.offsetWidth * 0.9; + const maxHeight = memeImage.offsetHeight * 0.25; + let fontSize = 100; + element.style.fontSize = fontSize + 'px'; + + while ((element.offsetWidth > maxWidth || element.offsetHeight > maxHeight) && fontSize > 10) { + fontSize--; + element.style.fontSize = fontSize + 'px'; + } +} + +function setImage(src) { + isDefaultImage = false; + memeImage.src = src; + memeImage.onload = () => { + enableInputs(); + updateSimpleMemeText(); + }; +} + +function resetToDefaultImage() { + if (!isDefaultImage) { + memeImage.src = defaultImageSrc; + isDefaultImage = true; + disableInputs(); + } +} + +function enableInputs() { + createMemeButton.disabled = false; + if (memeTypeSelect.value === 'simple') { + topTextInput.disabled = false; + bottomTextInput.disabled = false; + simpleFont.disabled = false; + } else { + customTextInput.disabled = false; + addTextBtn.disabled = false; + customFontSize.disabled = false; + customFont.disabled = false; + } +} + +function disableInputs() { + topTextInput.disabled = true; + bottomTextInput.disabled = true; + customTextInput.disabled = true; + addTextBtn.disabled = true; + createMemeButton.disabled = true; + simpleFont.disabled = true; + customFontSize.disabled = true; + customFont.disabled = true; + topTextInput.value = ''; + bottomTextInput.value = ''; + updateSimpleMemeText(); +} + +function switchMemeType() { + if (memeTypeSelect.value === 'simple') { + simpleTextInputs.style.display = 'block'; + customTextContainer.style.display = 'none'; + topTextOutput.style.display = 'block'; + bottomTextOutput.style.display = 'block'; + updateSimpleMemeText(); + } else { + simpleTextInputs.style.display = 'none'; + customTextContainer.style.display = 'block'; + topTextOutput.style.display = 'none'; + bottomTextOutput.style.display = 'none'; + } + if (!isDefaultImage) { + enableInputs(); + } +} + +function addCustomText() { + const text = customTextInput.value.trim(); + if (text) { + const textElement = document.createElement('div'); + textElement.className = 'meme-text'; + textElement.textContent = text; + textElement.style.left = '50%'; + textElement.style.top = '50%'; + textElement.style.transform = 'translate(-50%, -50%)'; + textElement.style.fontSize = customFontSize.value; + textElement.style.fontFamily = customFont.value; + memeContainer.appendChild(textElement); + customTextInput.value = ''; + makeDraggable(textElement); + } +} + +function makeDraggable(element) { + let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; + element.onmousedown = dragMouseDown; + + function dragMouseDown(e) { + e.preventDefault(); + pos3 = e.clientX; + pos4 = e.clientY; + document.onmouseup = closeDragElement; + document.onmousemove = elementDrag; + } + + function elementDrag(e) { + e.preventDefault(); + pos1 = pos3 - e.clientX; + pos2 = pos4 - e.clientY; + pos3 = e.clientX; + pos4 = e.clientY; + element.style.top = (element.offsetTop - pos2) + "px"; + element.style.left = (element.offsetLeft - pos1) + "px"; + } + + function closeDragElement() { + document.onmouseup = null; + document.onmousemove = null; + } +} + +topTextInput.addEventListener('input', updateSimpleMemeText); +bottomTextInput.addEventListener('input', updateSimpleMemeText); +memeTypeSelect.addEventListener('change', switchMemeType); +simpleFont.addEventListener('change', updateSimpleMemeText); + +imageFileInput.addEventListener('change', (event) => { + const file = event.target.files[0]; + if (file) { + const reader = new FileReader(); + reader.onload = (e) => setImage(e.target.result); + reader.readAsDataURL(file); + } +}); + +loadUrlImageButton.addEventListener('click', () => { + const imageUrl = imageUrlInput.value.trim(); + if (imageUrl) { + setImage(imageUrl); + } else { + alert('Please enter a valid image URL'); + } +}); + +memeImage.addEventListener('error', () => { + if (!isDefaultImage) { + alert('Failed to load image. Please try another URL or file.'); + resetToDefaultImage(); + } +}); + +createMemeButton.addEventListener('click', () => { + const customInputDisplay = customTextContainer.style.display; + customTextContainer.style.display = 'none'; + + html2canvas(memeContainer, { + useCORS: true, + allowTaint: true + }).then(canvas => { + customTextContainer.style.display = customInputDisplay; + + canvas.toBlob(blob => { + const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + + if (isMobile && navigator.share) { + const file = new File([blob], 'meme.png', { type: 'image/png' }); + navigator.share({ + files: [file], + title: 'Check out my meme!', + text: 'I created this meme using the Advanced Meme Creator.' + }).then(() => console.log('Shared successfully')) + .catch((error) => console.log('Error sharing:', error)); + } else { + // Download the image on desktop platforms + const link = document.createElement('a'); + link.download = 'meme.png'; + link.href = URL.createObjectURL(blob); + link.click(); + URL.revokeObjectURL(link.href); + } + }, 'image/png'); + }); +}); + +addTextBtn.addEventListener('click', addCustomText); + +window.addEventListener('resize', updateSimpleMemeText); + +// Initial state +switchMemeType(); +disableInputs(); \ No newline at end of file diff --git a/editor/styles.css b/editor/styles.css new file mode 100644 index 0000000..24f135b --- /dev/null +++ b/editor/styles.css @@ -0,0 +1,153 @@ +body { + font-family: 'Roboto', Arial, sans-serif; + max-width: 800px; + margin: 0 auto; + padding: 20px; + background-color: #f0f4f8; + color: #333; +} + +h1 { + text-align: center; + color: #2c3e50; + margin-bottom: 30px; +} + +.meme-container { + position: relative; + display: inline-block; + max-width: 100%; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + border-radius: 8px; + overflow: hidden; + margin-bottom: 20px; +} + +.meme-text { + position: absolute; + padding: 10px; + font-weight: bold; + text-align: center; + text-transform: uppercase; + color: white; + text-shadow: 2px 2px 0 #000, -2px -2px 0 #000, 2px -2px 0 #000, -2px 2px 0 #000; + cursor: move; + user-select: none; +} + +.top-text { top: 5%; left: 5%; right: 5%; } +.bottom-text { bottom: 5%; left: 5%; right: 5%; } + +input, button, select { + display: block; + width: 100%; + margin-bottom: 15px; + padding: 12px; + font-size: 16px; + border: 1px solid #ccc; + border-radius: 4px; + box-sizing: border-box; +} + +button { + background-color: #3498db; + color: white; + border: none; + cursor: pointer; + transition: background-color 0.3s ease; +} + +button:hover { background-color: #2980b9; } + +button:disabled { + background-color: #bdc3c7; + cursor: not-allowed; +} + +#memeImage { + max-width: 100%; + height: auto; + display: block; +} + +input:disabled, select:disabled { + background-color: #ecf0f1; + cursor: not-allowed; +} + +#customTextContainer { margin-top: 20px; } + +.custom-text-input { + display: flex; + margin-bottom: 15px; +} + +.custom-text-input input, .custom-text-input select { + flex-grow: 1; + margin-right: 10px; + margin-bottom: 0; +} + +.custom-text-input button { + width: auto; + padding: 12px 20px; +} + +.text-style-options { + display: flex; + justify-content: space-between; + margin-bottom: 15px; +} + +.text-style-options select { + width: 48%; +} + +#memeTypeSelect { + margin-bottom: 20px; +} + +.file-input-wrapper { + position: relative; + overflow: hidden; + display: inline-block; + width: 100%; +} + +.file-input-wrapper input[type=file] { + font-size: 100px; + position: absolute; + left: 0; + top: 0; + opacity: 0; + cursor: pointer; +} + +.file-input-wrapper .btn { + display: inline-block; + padding: 12px; + background-color: #3498db; + color: white; + text-align: center; + width: 100%; + box-sizing: border-box; +} + +#imageUrlInput { + margin-bottom: 10px; +} + +@media (max-width: 600px) { + body { + padding: 10px; + } + + .text-style-options { + flex-direction: column; + } + + .text-style-options select { + width: 100%; + margin-bottom: 10px; + } +} \ No newline at end of file