Asked by ABAINEH

CREAT THE BIRTHDAY CARD APP

All Answers 1

Answered by GPT-5 mini AI
I’ll create a simple, working birthday-card web app you can run locally right away. It supports selecting a template, editing recipient/name and message, uploading an image, previewing the card, and downloading the finished card as a PNG.

Files to create:
- index.html
- style.css
- script.js

Save each file and open index.html in your browser.

index.html
(put this content into a file named index.html)
```
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Birthday Card Maker</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="app">
<header>
<h1>Birthday Card Maker</h1>
</header>

<main>
<section class="controls">
<div class="control-row">
<label>Template:</label>
<select id="templateSelect">
<option value="classic">Classic</option>
<option value="modern">Modern</option>
<option value="party">Party</option>
</select>
</div>

<div class="control-row">
<label>Recipient name:</label>
<input id="recipientInput" type="text" placeholder="e.g., Sarah" />
</div>

<div class="control-row">
<label>Message:</label>
<textarea id="messageInput" rows="4" placeholder="Write your birthday message..."></textarea>
</div>

<div class="control-row">
<label>Upload photo (optional):</label>
<input id="photoInput" type="file" accept="image/*" />
</div>

<div class="control-row">
<label>Background color:</label>
<input id="bgColor" type="color" value="#ffefd5" />
</div>

<div class="control-row buttons">
<button id="downloadBtn">Download PNG</button>
<button id="printBtn">Print</button>
<button id="resetBtn">Reset</button>
</div>
</section>

<section class="preview">
<h2>Preview</h2>
<div id="card" class="card classic">
<div class="card-image-wrap">
<img id="cardImage" src="" alt="" />
<div id="imagePlaceholder">Add photo</div>
</div>
<div class="card-content">
<h1 id="cardTitle">Happy Birthday</h1>
<h3 id="cardRecipient"></h3>
<p id="cardMessage">Wishing you a wonderful birthday and a year full of joy!</p>
</div>
</div>
</section>
</main>

<footer>
<small>Simple birthday card maker — edit and download</small>
</footer>
</div>

<!-- html2canvas for export -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="script.js"></script>
</body>
</html>
```

style.css
(put this content into a file named style.css)
```
:root{
--app-bg: #f7f7f9;
--control-bg: #ffffff;
--card-w: 600px;
--card-h: 400px;
--accent: #ff6b6b;
}

*{box-sizing:border-box}
body{
margin:0;
font-family:system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial;
background:var(--app-bg);
color:#222;
}
.app{
max-width:1100px;
margin:24px auto;
padding:18px;
}
header h1{margin:0 0 12px 0}
main{
display:flex;
gap:20px;
align-items:flex-start;
}
.controls{
width:360px;
background:var(--control-bg);
padding:16px;
border-radius:8px;
box-shadow:0 2px 8px rgba(0,0,0,0.06);
}
.control-row{
margin-bottom:12px;
display:flex;
flex-direction:column;
}
.control-row label{
font-weight:600;
margin-bottom:6px;
}
.control-row input[type="text"],
.control-row select,
.control-row textarea,
.control-row input[type="color"]{
padding:8px;
border-radius:6px;
border:1px solid #ddd;
font-size:14px;
}
.control-row.buttons{
display:flex;
gap:8px;
}
button{
padding:10px 12px;
border-radius:6px;
border: none;
background:var(--accent);
color:#fff;
cursor:pointer;
}
button:hover{opacity:0.95}
.preview{
flex:1;
}
.preview h2{margin-top:0}
.card{
width:var(--card-w);
height:var(--card-h);
border-radius:12px;
box-shadow:0 8px 30px rgba(0,0,0,0.12);
overflow:hidden;
display:flex;
flex-direction:column;
align-items:stretch;
background:linear-gradient(180deg,#fff,#fff);
}

/* image area */
.card-image-wrap{
height:45%;
background:#f0f0f0;
position:relative;
display:flex;
align-items:center;
justify-content:center;
overflow:hidden;
}
.card-image-wrap img{
max-width:100%;
max-height:100%;
display:block;
}
#imagePlaceholder{
position:absolute;
color:#666;
font-weight:600;
}

/* content area */
.card-content{
padding:18px;
text-align:center;
display:flex;
flex-direction:column;
justify-content:center;
gap:6px;
height:55%;
}
.card-content h1{
margin:0;
font-size:28px;
letter-spacing:0.5px;
}
.card-content h3{
margin:0;
font-weight:600;
color:#444;
}
.card-content p{
margin:6px 0 0 0;
color:#333;
}

/* template variations */
.card.classic{ background:linear-gradient(180deg,#fff7ec,#fff) }
.card.modern{ background:linear-gradient(180deg,#e7f7ff,#ffffff) }
.card.party{ background:linear-gradient(180deg,#fff0fb,#fff) }

/* small screens */
@media (max-width:900px){
main{flex-direction:column}
.controls{width:100%}
.card{width:100%; max-width:600px}
}
```

script.js
(put this content into a file named script.js)
```
const templateSelect = document.getElementById('templateSelect');
const recipientInput = document.getElementById('recipientInput');
const messageInput = document.getElementById('messageInput');
const photoInput = document.getElementById('photoInput');
const bgColorInput = document.getElementById('bgColor');

const card = document.getElementById('card');
const cardTitle = document.getElementById('cardTitle');
const cardRecipient = document.getElementById('cardRecipient');
const cardMessage = document.getElementById('cardMessage');
const cardImage = document.getElementById('cardImage');
const imagePlaceholder = document.getElementById('imagePlaceholder');

const downloadBtn = document.getElementById('downloadBtn');
const printBtn = document.getElementById('printBtn');
const resetBtn = document.getElementById('resetBtn');

// Initialize
function applyTemplate(t){
card.classList.remove('classic','modern','party');
card.classList.add(t);
}
applyTemplate(templateSelect.value);

// Events
templateSelect.addEventListener('change', e => {
applyTemplate(e.target.value);
});

recipientInput.addEventListener('input', e => {
const v = e.target.value.trim();
cardRecipient.textContent = v ? `Dear ${v},` : '';
});

messageInput.addEventListener('input', e => {
cardMessage.textContent = e.target.value || 'Wishing you a wonderful birthday and a year full of joy!';
});

bgColorInput.addEventListener('input', e => {
const color = e.target.value;
card.style.background = color;
// if you want to keep templates' look, comment the above line and use CSS templates
});

// Photo upload
photoInput.addEventListener('change', e=>{
const file = e.target.files[0];
if(!file) return;
const reader = new FileReader();
reader.onload = function(ev){
cardImage.src = ev.target.result;
cardImage.style.display = 'block';
imagePlaceholder.style.display = 'none';
};
reader.readAsDataURL(file);
});

// Download using html2canvas
downloadBtn.addEventListener('click', async () => {
// temporarily remove controls or scale adjustments if needed
const oldTransform = card.style.transform;
// increase scale for better resolution
const scale = 2;
const origWidth = card.offsetWidth;
const origHeight = card.offsetHeight;

// Use html2canvas
html2canvas(card, { scale: scale, useCORS: true }).then(canvas=>{
const link = document.createElement('a');
link.download = `birthday-card.png`;
link.href = canvas.toDataURL('image/png');
link.click();
}).catch(err=>{
alert('Error exporting image: ' + err.message);
}).finally(()=>{
card.style.transform = oldTransform;
});
});

printBtn.addEventListener('click', () => {
// open new window with only the card for printing
html2canvas(card, { scale: 2, useCORS:true }).then(canvas=>{
const dataUrl = canvas.toDataURL('image/png');
const w = window.open('');
w.document.write('<img src="'+dataUrl+'" style="max-width:100%;"/>');
w.document.title = 'Print birthday card';
w.focus();
w.print();
});
});

resetBtn.addEventListener('click', () => {
recipientInput.value = '';
messageInput.value = '';
photoInput.value = '';
cardImage.src = '';
cardImage.style.display = 'none';
imagePlaceholder.style.display = 'block';
applyTemplate('classic');
bgColorInput.value = '#ffefd5';
card.style.background = '';
cardRecipient.textContent = '';
cardMessage.textContent = 'Wishing you a wonderful birthday and a year full of joy!';
});
```

How to run
- Place the three files in the same folder.
- Open index.html in a modern browser (Chrome, Firefox, Edge).
- Edit fields, upload a photo, choose template, then click "Download PNG".

Notes and next steps (optional enhancements)
- Save/share: add a backend to save cards (e.g., Node/Express + S3 / database) and generate shareable links.
- Templates: add more templates, fonts, sticker/emoji overlays, and drag/resize of the uploaded image (use interact.js or fabric.js).
- Mobile app: wrap in Capacitor or build with React Native / Flutter for push notifications and scheduled sending.
- Email/schedule: add server-side scheduling (e.g., cron jobs, queue) to email the card on a selected date.
- Higher-resolution export: render on a larger off-screen canvas for print-quality output or use vector templates.

If you want, I can:
- Extend this to let users position/resize images and text.
- Add social sharing (Facebook, Twitter, WhatsApp).
- Turn it into a small React app or mobile app template (React Native / Flutter).
Tell me which direction you prefer and I’ll continue.