- Create responsive HTML/CSS/JS website for Top 500 Albums - Add modern design with gradient background and glassmorphism effects - Implement search, filtering, and sorting functionality - Add reverse button for toggling sort order - Create bookmark system with jump-to-rank functionality - Add individual album share buttons with state preservation - Implement URL parameter handling for shareable links - Add favicon with vinyl record design - Create mobile-responsive layout with larger album covers - Add smooth animations and visual feedback throughout - Smart URL management: clean URLs for rank 1, parameterized for others 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
157 lines
No EOL
5.4 KiB
HTML
157 lines
No EOL
5.4 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Create Favicon</title>
|
|
</head>
|
|
<body>
|
|
<canvas id="canvas" width="32" height="32" style="border: 1px solid #000; transform: scale(10);"></canvas>
|
|
<br><br>
|
|
<button onclick="downloadFavicon()">Download Favicon</button>
|
|
|
|
<script>
|
|
const canvas = document.getElementById('canvas');
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Create favicon design
|
|
function createFavicon() {
|
|
// Clear canvas
|
|
ctx.clearRect(0, 0, 32, 32);
|
|
|
|
// Background gradient (purple/blue theme)
|
|
const gradient = ctx.createLinearGradient(0, 0, 32, 32);
|
|
gradient.addColorStop(0, '#667eea');
|
|
gradient.addColorStop(1, '#764ba2');
|
|
|
|
// Fill background
|
|
ctx.fillStyle = gradient;
|
|
ctx.fillRect(0, 0, 32, 32);
|
|
|
|
// Add vinyl record design
|
|
ctx.fillStyle = '#1a1a1a';
|
|
ctx.beginPath();
|
|
ctx.arc(16, 16, 14, 0, 2 * Math.PI);
|
|
ctx.fill();
|
|
|
|
// Center hole
|
|
ctx.fillStyle = gradient;
|
|
ctx.beginPath();
|
|
ctx.arc(16, 16, 4, 0, 2 * Math.PI);
|
|
ctx.fill();
|
|
|
|
// Add grooves
|
|
ctx.strokeStyle = '#333';
|
|
ctx.lineWidth = 1;
|
|
for (let r = 6; r <= 12; r += 2) {
|
|
ctx.beginPath();
|
|
ctx.arc(16, 16, r, 0, 2 * Math.PI);
|
|
ctx.stroke();
|
|
}
|
|
|
|
// Add number "500" in small text
|
|
ctx.fillStyle = 'white';
|
|
ctx.font = 'bold 6px Arial';
|
|
ctx.textAlign = 'center';
|
|
ctx.fillText('500', 16, 28);
|
|
}
|
|
|
|
function downloadFavicon() {
|
|
// Create multiple sizes for ICO file
|
|
const sizes = [16, 32, 48];
|
|
const images = [];
|
|
|
|
sizes.forEach(size => {
|
|
const tempCanvas = document.createElement('canvas');
|
|
tempCanvas.width = size;
|
|
tempCanvas.height = size;
|
|
const tempCtx = tempCanvas.getContext('2d');
|
|
|
|
// Scale the design
|
|
const scale = size / 32;
|
|
tempCtx.scale(scale, scale);
|
|
|
|
// Redraw for this size
|
|
// Background gradient
|
|
const gradient = tempCtx.createLinearGradient(0, 0, 32, 32);
|
|
gradient.addColorStop(0, '#667eea');
|
|
gradient.addColorStop(1, '#764ba2');
|
|
|
|
tempCtx.fillStyle = gradient;
|
|
tempCtx.fillRect(0, 0, 32, 32);
|
|
|
|
// Vinyl record
|
|
tempCtx.fillStyle = '#1a1a1a';
|
|
tempCtx.beginPath();
|
|
tempCtx.arc(16, 16, 14, 0, 2 * Math.PI);
|
|
tempCtx.fill();
|
|
|
|
// Center hole
|
|
tempCtx.fillStyle = gradient;
|
|
tempCtx.beginPath();
|
|
tempCtx.arc(16, 16, 4, 0, 2 * Math.PI);
|
|
tempCtx.fill();
|
|
|
|
// Grooves
|
|
if (size >= 24) {
|
|
tempCtx.strokeStyle = '#333';
|
|
tempCtx.lineWidth = 1;
|
|
for (let r = 6; r <= 12; r += 2) {
|
|
tempCtx.beginPath();
|
|
tempCtx.arc(16, 16, r, 0, 2 * Math.PI);
|
|
tempCtx.stroke();
|
|
}
|
|
}
|
|
|
|
// "500" text (only for larger sizes)
|
|
if (size >= 24) {
|
|
tempCtx.fillStyle = 'white';
|
|
tempCtx.font = 'bold 6px Arial';
|
|
tempCtx.textAlign = 'center';
|
|
tempCtx.fillText('500', 16, 28);
|
|
}
|
|
|
|
// Convert to blob
|
|
const imageData = tempCtx.getImageData(0, 0, size, size);
|
|
images.push({size, imageData});
|
|
});
|
|
|
|
// Download as PNG (browsers don't support ICO creation directly)
|
|
const link = document.createElement('a');
|
|
link.download = 'favicon-32x32.png';
|
|
link.href = canvas.toDataURL();
|
|
link.click();
|
|
|
|
// Also create 16x16 version
|
|
const canvas16 = document.createElement('canvas');
|
|
canvas16.width = 16;
|
|
canvas16.height = 16;
|
|
const ctx16 = canvas16.getContext('2d');
|
|
ctx16.scale(0.5, 0.5);
|
|
|
|
const gradient16 = ctx16.createLinearGradient(0, 0, 32, 32);
|
|
gradient16.addColorStop(0, '#667eea');
|
|
gradient16.addColorStop(1, '#764ba2');
|
|
|
|
ctx16.fillStyle = gradient16;
|
|
ctx16.fillRect(0, 0, 32, 32);
|
|
|
|
ctx16.fillStyle = '#1a1a1a';
|
|
ctx16.beginPath();
|
|
ctx16.arc(16, 16, 14, 0, 2 * Math.PI);
|
|
ctx16.fill();
|
|
|
|
ctx16.fillStyle = gradient16;
|
|
ctx16.beginPath();
|
|
ctx16.arc(16, 16, 4, 0, 2 * Math.PI);
|
|
ctx16.fill();
|
|
|
|
const link16 = document.createElement('a');
|
|
link16.download = 'favicon-16x16.png';
|
|
link16.href = canvas16.toDataURL();
|
|
link16.click();
|
|
}
|
|
|
|
// Create the favicon on load
|
|
createFavicon();
|
|
</script>
|
|
</body>
|
|
</html> |