madebydanny.uk written in html, css, and a lot of JavaScript I don't understand madebydanny.uk
html css javascript
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 165 lines 6.2 kB view raw
1// ── Photo data ──────────────────────────────────────────────────────────────── 2 3const PHOTOS = [ 4 { 5 src: 'https://imrs.madebydanny.uk/https://cloudflareisawesome.madebydanny.uk/photos-upload-1/20240622_235041500_iOS.jpg', 6 title: 'DSC_3811.jpg', 7 date: '2025-10-14' 8 }, 9 { 10 src: 'https://imrs.madebydanny.uk/https://cloudflareisawesome.madebydanny.uk/photos-upload-1/DSC_3773.jpg', 11 title: 'DSC_3773.jpg', 12 date: '2025-10-14' 13 }, 14 { 15 src: 'https://imrs.madebydanny.uk/https://cloudflareisawesome.madebydanny.uk/photos-upload-1/DSC_3766.jpg', 16 title: 'DSC_3766.jpg', 17 date: '2025-10-14' 18 }, 19 { 20 src: 'https://imrs.madebydanny.uk/https://cloudflareisawesome.madebydanny.uk/photos-upload-1/DSC_3765.jpg', 21 title: 'DSC_3765.jpg', 22 date: '2025-10-14' 23 }, 24 { 25 src: 'https://imrs.madebydanny.uk/https://cloudflareisawesome.madebydanny.uk/photos-upload-1/DSC_3704.jpg', 26 title: 'DSC_3704.jpg', 27 date: '2025-10-14' 28 }, 29 { 30 src: 'https://imrs.madebydanny.uk/https://cloudflareisawesome.madebydanny.uk/photos-upload-1/DSC_3692.jpg', 31 title: 'DSC_3692.jpg', 32 date: '2025-10-14' 33 }, 34 { 35 src: 'https://imrs.madebydanny.uk/https://cloudflareisawesome.madebydanny.uk/photos-upload-1/20240622_234015800_iOS.jpg', 36 title: 'DSC_3683.jpg', 37 date: '2025-10-14' 38 } 39]; 40 41// ── Modal ───────────────────────────────────────────────────────────────────── 42 43function openPhotoModal(src, alt) { 44 const modal = document.getElementById('photo-modal'); 45 const modalImg = document.getElementById('modal-photo'); 46 if (!modal || !modalImg) return; 47 modalImg.src = src; 48 modalImg.alt = alt; 49 modal.classList.add('active'); 50 document.body.style.overflow = 'hidden'; 51} 52 53function closePhotoModal() { 54 const modal = document.getElementById('photo-modal'); 55 if (!modal) return; 56 modal.classList.remove('active'); 57 document.body.style.overflow = ''; 58} 59 60// ── Home strip (4 most recent photos) ──────────────────────────────────────── 61 62function renderHomePhotos() { 63 const strip = document.getElementById('home-photo-strip'); 64 if (!strip) return; 65 66 const recent = PHOTOS.slice(0, 4); 67 strip.innerHTML = ''; 68 69 recent.forEach(photo => { 70 const item = document.createElement('div'); 71 item.className = 'photo-strip-item'; 72 item.setAttribute('role', 'button'); 73 item.setAttribute('tabindex', '0'); 74 item.setAttribute('aria-label', `View photo: ${photo.title}`); 75 76 const img = document.createElement('img'); 77 img.src = photo.src; 78 img.alt = photo.title; 79 img.loading = 'lazy'; 80 81 item.appendChild(img); 82 item.addEventListener('click', () => openPhotoModal(photo.src, photo.title)); 83 item.addEventListener('keydown', (e) => { 84 if (e.key === 'Enter' || e.key === ' ') openPhotoModal(photo.src, photo.title); 85 }); 86 87 strip.appendChild(item); 88 }); 89} 90 91// ── Full gallery (photos.html) ──────────────────────────────────────────────── 92 93function renderPhotosGallery() { 94 const gallery = document.getElementById('photos-gallery'); 95 const emptyState = document.getElementById('empty-photos'); 96 if (!gallery) return; 97 98 gallery.innerHTML = ''; 99 100 if (PHOTOS.length === 0) { 101 if (emptyState) emptyState.style.display = 'block'; 102 return; 103 } 104 if (emptyState) emptyState.style.display = 'none'; 105 106 PHOTOS.forEach(photo => { 107 const item = document.createElement('div'); 108 item.className = 'photo-item'; 109 item.setAttribute('role', 'button'); 110 item.setAttribute('tabindex', '0'); 111 item.setAttribute('aria-label', `View photo: ${photo.title}`); 112 113 const img = document.createElement('img'); 114 img.src = photo.src; 115 img.alt = photo.title; 116 img.loading = 'lazy'; 117 118 const info = document.createElement('div'); 119 info.className = 'photo-info'; 120 121 const title = document.createElement('h3'); 122 title.className = 'photo-title'; 123 title.textContent = photo.title; 124 125 const date = document.createElement('p'); 126 date.className = 'photo-date'; 127 date.textContent = new Date(photo.date).toLocaleDateString('en-GB', { 128 year: 'numeric', month: 'short', day: 'numeric' 129 }); 130 131 info.appendChild(title); 132 info.appendChild(date); 133 item.appendChild(img); 134 item.appendChild(info); 135 136 item.addEventListener('click', () => openPhotoModal(photo.src, photo.title)); 137 item.addEventListener('keydown', (e) => { 138 if (e.key === 'Enter' || e.key === ' ') openPhotoModal(photo.src, photo.title); 139 }); 140 141 gallery.appendChild(item); 142 }); 143} 144 145// ── Init ────────────────────────────────────────────────────────────────────── 146 147document.addEventListener('DOMContentLoaded', () => { 148 // Render whichever surface is present on this page 149 renderHomePhotos(); 150 renderPhotosGallery(); 151 152 // Modal wiring (used on both pages) 153 const modal = document.getElementById('photo-modal'); 154 const closeBtn = document.getElementById('modal-close'); 155 156 if (closeBtn) closeBtn.addEventListener('click', closePhotoModal); 157 158 if (modal) { 159 modal.addEventListener('click', e => { if (e.target === modal) closePhotoModal(); }); 160 } 161 162 document.addEventListener('keydown', e => { 163 if (e.key === 'Escape') closePhotoModal(); 164 }); 165});