Skip to content

Commit

Permalink
New greeting page
Browse files Browse the repository at this point in the history
  • Loading branch information
mskian committed Dec 9, 2024
1 parent ecd12ec commit 5fbd4ef
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Christmas Greetings: Linux Terminal Style Greeting Wishes with Name.
![Christmas Greetings](https://raw.githubusercontent.com/mskian/christmas-wishes/main/images/christmas-greeting-1733505285020.png)

- **Create Christmas Greeting Wish image with image : <https://christmas.sanweb.info/>**
- **Christmas Wishing Songs: <https://christmas.sanweb.info/music>**
- **Christmas Wishing Songs: <https://christmas.sanweb.info/music>**
- **Christmas Greeting image with Name: <https://christmas.sanweb.info/greeting>**

## Credits

Expand Down
40 changes: 40 additions & 0 deletions css/greeting.css
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;
}
85 changes: 85 additions & 0 deletions greeting.html
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>
Binary file added images/christmas-wishes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions js/greeting.js
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>`;
}
});
});

0 comments on commit 5fbd4ef

Please sign in to comment.