-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
230 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
html, body { | ||
min-height: 100vh; | ||
font-family: "Catamaran", sans-serif; | ||
} | ||
body { | ||
background: #A02334; | ||
color: #f0dd71; | ||
font-family: "Catamaran", sans-serif; | ||
font-weight: 600; | ||
padding-bottom: 20px; | ||
} | ||
|
||
.terminal { | ||
background-color: #1e272e; | ||
padding: 20px; | ||
font-family: "Catamaran", sans-serif; | ||
border-radius: 8px; | ||
box-shadow: 0 0 10px #bdf399; | ||
} | ||
|
||
input:focus, button:focus { | ||
outline: none; | ||
border-color: #ff3860; | ||
box-shadow: 0 0 0 0.125em rgba(255, 56, 96, 0.25); | ||
} | ||
.input { | ||
font-family: "Catamaran", sans-serif; | ||
} | ||
.button { | ||
font-family: "Catamaran", sans-serif; | ||
font-weight: bold; | ||
} | ||
#generatedImage { | ||
font-family: "Catamaran", sans-serif;; | ||
border: 2px solid #ff3860; | ||
border-radius: 8px; | ||
} | ||
p { | ||
font-family: "Catamaran", sans-serif; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
|
||
<link rel="icon" type="image/png" sizes="196x196" href="icon/icon-192.png" /> | ||
<link rel="shortcut icon" type="image/x-icon" href="icon/favicon.ico" /> | ||
|
||
<title>Christmas Greeting image with Name</title> | ||
<meta name="description" content="Christmas Greeting image with Name: Just Enter your Name and Generate Greeting image with your Name."/> | ||
|
||
<link rel="preconnect" href="https://cdnjs.cloudflare.com"> | ||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.4/css/bulma.min.css" integrity="sha512-HqxHUkJM0SYcbvxUw5P60SzdOTy/QVwA1JJrvaXJv4q7lmbDZCmZaqz01UPOaQveoxfYRv1tHozWGPMcuTBuvQ==" crossorigin="anonymous" referrerpolicy="no-referrer" /> | ||
<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=Catamaran:[email protected]&display=swap" rel="stylesheet"> | ||
<link rel="stylesheet" href="css/greeting.css"> | ||
|
||
<script> | ||
const canonicalLink = document.createElement('link'); | ||
canonicalLink.setAttribute('rel', 'canonical'); | ||
canonicalLink.setAttribute('href', window.location.href); | ||
document.head.appendChild(canonicalLink); | ||
</script> | ||
|
||
</head> | ||
<body> | ||
<section class="hero is-fullheight"> | ||
<div class="hero-body"> | ||
<div class="container"> | ||
<div class="columns is-centered"> | ||
<div class="column is-6"> | ||
<div class="box terminal"> | ||
<h1 class="title has-text-danger is-size-5 has-text-centered">🎄 Christmas Greeting Image 🎅</h1> | ||
<hr> | ||
<div id="output"> | ||
<p class="has-text-danger">🟢 Please Rnter your name to generate a Christmas greeting ...</p> | ||
</div> | ||
<br> | ||
<form id="nameForm"> | ||
<div class="field"> | ||
<label for="name" class="label has-text-danger">Your Name:</label> | ||
<div class="control"> | ||
<input | ||
type="text" | ||
id="name" | ||
class="input is-danger" | ||
placeholder="Enter your name" | ||
required | ||
minlength="2" | ||
maxlength="36" | ||
title="Name should only contain letters and spaces" | ||
> | ||
</div> | ||
</div> | ||
<div class="field"> | ||
<button type="submit" class="button is-danger is-fullwidth">Generate Greeting</button> | ||
</div> | ||
</form> | ||
<hr> | ||
<div id="progressContainer" class="is-hidden"> | ||
<progress class="progress is-danger" value="0" max="100">0%</progress> | ||
<p class="has-text-danger has-text-centered">ℹ️ Generating your Christmas greeting</p> | ||
</div> | ||
<div id="greetingImage" class="is-hidden mt-4"> | ||
<p class="has-text-danger has-text-centered">🥳 Your greeting is ready</p><br> | ||
<figure class="image is-centered"> | ||
<img src="" alt="Christmas Greeting" id="generatedImage"> | ||
</figure> | ||
<a class="button is-danger is-fullwidth mt-3" id="downloadImage" download="christmas-greeting.png">Download Greeting</a> | ||
<br> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</section> | ||
|
||
<script src="js/greeting.js"></script> | ||
|
||
</body> | ||
</html> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
document.addEventListener('DOMContentLoaded', () => { | ||
const nameForm = document.getElementById('nameForm'); | ||
const nameInput = document.getElementById('name'); | ||
const progressContainer = document.getElementById('progressContainer'); | ||
const progressBar = progressContainer.querySelector('progress'); | ||
const output = document.getElementById('output'); | ||
const greetingImage = document.getElementById('greetingImage'); | ||
const generatedImage = document.getElementById('generatedImage'); | ||
const downloadImage = document.getElementById('downloadImage'); | ||
const backgroundImagePath = './images/christmas-wishes.png'; | ||
|
||
const sanitizeInput = (input) => { | ||
const tempDiv = document.createElement('div'); | ||
tempDiv.textContent = input.trim(); | ||
return tempDiv.innerHTML; | ||
}; | ||
|
||
const validateInput = (name) => { | ||
if (!name || name.length < 2 || name.length > 36) { | ||
throw new Error('Name must be between 2 and 36 characters.'); | ||
} | ||
}; | ||
|
||
const generateGreetingImage = (name) => { | ||
return new Promise((resolve, reject) => { | ||
const img = new Image(); | ||
img.src = backgroundImagePath; | ||
img.onload = () => { | ||
const canvas = document.createElement('canvas'); | ||
canvas.width = img.width; | ||
canvas.height = img.height; | ||
|
||
const ctx = canvas.getContext('2d'); | ||
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | ||
|
||
// ctx.fillStyle = '#d35585'; // Dark pink | ||
ctx.font = 'bold 36px "Catamaran", sans-serif'; | ||
ctx.textAlign = 'center'; | ||
// ctx.fillText('🎄 Merry Christmas 🎄', canvas.width / 2, 90); | ||
|
||
ctx.fillStyle = '#130f40'; // Brown | ||
ctx.font = 'bold 30px "Catamaran", sans-serif'; | ||
ctx.fillText(`${name}`, canvas.width / 2, canvas.height - 60); | ||
|
||
resolve(canvas.toDataURL('image/png')); | ||
}; | ||
img.onerror = () => reject(new Error('Failed to load the background image.')); | ||
}); | ||
}; | ||
|
||
const terminalProcess = async (steps) => { | ||
for (const step of steps) { | ||
output.innerHTML += `<p class="has-text-danger" style="font-family: 'Catamaran', sans-serif;">${step}</p>`; | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
} | ||
}; | ||
|
||
const showProgress = async () => { | ||
progressContainer.classList.remove('is-hidden'); | ||
for (let i = 0; i <= 100; i++) { | ||
await new Promise((resolve) => setTimeout(resolve, 30)); | ||
progressBar.value = i; | ||
} | ||
progressContainer.classList.add('is-hidden'); | ||
}; | ||
|
||
nameForm.addEventListener('submit', async (e) => { | ||
e.preventDefault(); | ||
|
||
const name = sanitizeInput(nameInput.value); | ||
|
||
try { | ||
output.innerHTML = ''; | ||
greetingImage.classList.add('is-hidden'); | ||
|
||
validateInput(name); | ||
|
||
await terminalProcess([ | ||
'ℹ️ Validating input ...', | ||
'✅ Input validation successful', | ||
'🥤 Loading resources ...', | ||
'ℹ️ Preparing your greeting ...', | ||
]); | ||
|
||
nameInput.value = ''; | ||
|
||
await showProgress(); | ||
|
||
const imageSrc = await generateGreetingImage(name); | ||
|
||
generatedImage.src = imageSrc; | ||
downloadImage.href = imageSrc; | ||
const timestamp = new Date().getTime(); | ||
downloadImage.download = `christmas-greeting-${timestamp}.png`; | ||
greetingImage.classList.remove('is-hidden'); | ||
|
||
output.innerHTML += `<p class="has-text-danger" style="font-family: 'Catamaran', sans-serif;">🎉 Greeting generated successfully</p>`; | ||
} catch (err) { | ||
output.innerHTML += `<p class="has-text-danger" style="font-family: 'Catamaran', sans-serif;">🔴 ${err.message}</p>`; | ||
} | ||
}); | ||
}); | ||
|