Files
Todo/scripts/generate-png-icons.html
Paul Bailey 6cb9a593d4 feat: Add PWA assets and metadata for iOS Safari installation
- Generate app icons in multiple sizes (192x192, 512x512, 180x180, 32x32)
- Create favicon and apple-touch-icon SVG files
- Add comprehensive PWA meta tags in app layout
- Configure theme color (#3B82F6) and background color
- Update manifest.json with icon references (PNG and SVG)
- Create icon generation scripts (SVG and PNG conversion)
- Add browser-based PNG icon generator (HTML)
- Create comprehensive PWA testing guide
- Add icon setup documentation

Requirements: 4.1, 4.2
Task: 13. Add PWA assets and metadata
2025-12-01 20:39:11 +00:00

227 lines
6.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PWA Icon Generator</title>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 800px;
margin: 40px auto;
padding: 20px;
background: #f5f5f5;
}
.container {
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
h1 {
color: #3B82F6;
margin-top: 0;
}
.icon-preview {
display: flex;
gap: 20px;
margin: 20px 0;
flex-wrap: wrap;
}
.icon-item {
text-align: center;
}
canvas {
border: 1px solid #ddd;
border-radius: 4px;
display: block;
margin: 10px 0;
}
button {
background: #3B82F6;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin: 5px;
}
button:hover {
background: #2563EB;
}
.instructions {
background: #f0f9ff;
border-left: 4px solid #3B82F6;
padding: 15px;
margin: 20px 0;
}
.success {
color: #059669;
font-weight: 500;
}
</style>
</head>
<body>
<div class="container">
<h1>🎨 Ultimate Lists PWA Icon Generator</h1>
<div class="instructions">
<strong>Instructions:</strong>
<ol>
<li>Click "Generate All Icons" below</li>
<li>Click each "Download" button to save the PNG files</li>
<li>Save the files to your <code>public/</code> directory with the exact names shown</li>
<li>Refresh your PWA to see the new icons</li>
</ol>
</div>
<button onclick="generateAllIcons()" style="font-size: 16px; padding: 12px 24px;">
Generate All Icons
</button>
<div id="icons" class="icon-preview"></div>
</div>
<script>
function drawIcon(canvas, size) {
const ctx = canvas.getContext('2d');
const scale = size / 512;
// Clear canvas
ctx.clearRect(0, 0, size, size);
// Draw rounded rectangle background
const cornerRadius = size * 0.25;
ctx.fillStyle = '#3B82F6';
ctx.beginPath();
ctx.roundRect(0, 0, size, size, cornerRadius);
ctx.fill();
// Draw checkmark
ctx.strokeStyle = 'white';
ctx.lineWidth = size * 0.08;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.beginPath();
ctx.moveTo(size * 0.3, size * 0.5);
ctx.lineTo(size * 0.45, size * 0.65);
ctx.lineTo(size * 0.7, size * 0.35);
ctx.stroke();
// Draw list lines
ctx.fillStyle = 'white';
// First line
const line1X = size * 0.25;
const line1Y = size * 0.6;
const line1Width = size * 0.5;
const line1Height = size * 0.08;
const lineRadius = size * 0.02;
ctx.beginPath();
ctx.roundRect(line1X, line1Y, line1Width, line1Height, lineRadius);
ctx.fill();
// Second line
const line2X = size * 0.25;
const line2Y = size * 0.72;
const line2Width = size * 0.4;
const line2Height = size * 0.08;
ctx.beginPath();
ctx.roundRect(line2X, line2Y, line2Width, line2Height, lineRadius);
ctx.fill();
}
function downloadCanvas(canvas, filename) {
const link = document.createElement('a');
link.download = filename;
link.href = canvas.toDataURL('image/png');
link.click();
}
function createIconElement(size, filename) {
const div = document.createElement('div');
div.className = 'icon-item';
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
drawIcon(canvas, size);
const label = document.createElement('div');
label.textContent = `${size}x${size}`;
label.style.fontWeight = '500';
label.style.marginBottom = '5px';
const filenameLabel = document.createElement('div');
filenameLabel.textContent = filename;
filenameLabel.style.fontSize = '12px';
filenameLabel.style.color = '#666';
filenameLabel.style.marginBottom = '10px';
const button = document.createElement('button');
button.textContent = 'Download';
button.onclick = () => {
downloadCanvas(canvas, filename);
button.textContent = '✓ Downloaded';
button.style.background = '#059669';
setTimeout(() => {
button.textContent = 'Download';
button.style.background = '#3B82F6';
}, 2000);
};
div.appendChild(label);
div.appendChild(filenameLabel);
div.appendChild(canvas);
div.appendChild(button);
return div;
}
function generateAllIcons() {
const iconsContainer = document.getElementById('icons');
iconsContainer.innerHTML = '';
const icons = [
{ size: 192, filename: 'icon-192.png' },
{ size: 512, filename: 'icon-512.png' },
{ size: 180, filename: 'apple-touch-icon.png' },
{ size: 32, filename: 'favicon-32.png' }
];
icons.forEach(icon => {
iconsContainer.appendChild(createIconElement(icon.size, icon.filename));
});
// Add download all button
const downloadAllBtn = document.createElement('button');
downloadAllBtn.textContent = 'Download All Icons';
downloadAllBtn.style.fontSize = '16px';
downloadAllBtn.style.padding = '12px 24px';
downloadAllBtn.style.marginTop = '20px';
downloadAllBtn.onclick = () => {
icons.forEach((icon, index) => {
setTimeout(() => {
const canvas = iconsContainer.querySelectorAll('canvas')[index];
downloadCanvas(canvas, icon.filename);
}, index * 500);
});
downloadAllBtn.textContent = '✓ All Icons Downloaded';
downloadAllBtn.style.background = '#059669';
};
iconsContainer.appendChild(downloadAllBtn);
}
// Auto-generate on load
window.onload = () => {
generateAllIcons();
};
</script>
</body>
</html>