spectra/templates/index.html
2024-11-05 13:55:44 -05:00

283 lines
8.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tanishq Dubey Photography</title>
<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=Noto+Sans+Mono:wght@100..900&display=swap" rel="stylesheet">
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background-color: #f0f0f0;
display: flex;
flex-direction: row;
}
.main-content {
flex-grow: 1;
padding: 20px;
}
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(10px, 1fr));
grid-auto-rows: 10px;
grid-auto-flow: dense;
gap: 15px;
max-width: 100%;
box-sizing: border-box;
}
.polaroid {
position: relative;
background-color: #e8e8ea;
box-shadow: 0 0 2px 0 #f4f4f6 inset,
1px 5px 5px 0px #99999955;
border-radius: 2px;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
transition: background-color 0.3s ease;
max-width: 100%;
box-sizing: border-box;
}
.polaroid img {
max-width: 100%;
height: auto;
display: block;
}
.date-overlay {
position: absolute;
bottom: 4rem;
font-size: 1rem;
padding-right: 10px;
color: #ff6600;
padding: 2px 5px;
font-family: "Noto Sans Mono", monospace;
font-size: 0.7rem;
opacity: 0;
text-shadow: 0 0 2px #ff6600;
transition: opacity 0.3s ease;
}
.polaroid:hover .date-overlay {
opacity: 0.8;
}
.polaroid .caption {
margin-top: 10px;
display: block;
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
align-self: flex-end;
order: 0;
text-align: right;
line-height: 70%;
font-size: 0.75rem;
}
.noto-sans-mono-font {
font-family: "Noto Sans Mono", monospace;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
font-variation-settings:
"wdth" 100;
}
.sidebar {
min-width: 20rem;
background-color: #f0f0f0;
padding: 20px;
box-sizing: border-box;
position: sticky;
top: 0;
height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.sidebar-title {
font-size: 1rem;
text-align: right;
}
.sidebar-nav {
font-size: 1rem;
flex-grow: 1;
justify-content: center;
text-align: right;
}
.sidebar-nav ul {
list-style-type: none;
padding: 0;
}
.sidebar-nav a {
text-decoration: none;
color: #ff6600;
}
@media (max-width: 768px) {
body {
flex-direction: column;
}
.sidebar {
width: 100%;
height: auto;
position: static;
padding: 10px;
}
.main-content {
padding: 10px;
}
.grid-container {
display: flex;
flex-direction: column;
gap: 20px;
}
.polaroid {
width: 100%;
max-width: 100vw;
height: auto;
}
}
@media (min-width: 769px) and (max-width: 1024px) {
.grid-container {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}
}
</style>
</head>
<body>
<div class="sidebar">
<div class="sidebar-nav noto-sans-mono-font">
<nav>
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
<!-- divider line -->
<li><hr></li>
<li>Powered by <a href="https://dws.rip">DWS</a></li>
</ul>
</nav>
</div>
<div class="sidebar-title noto-sans-mono-font">
<h1>Tanishq Dubey Photography</h1>
</div>
</div>
<div class="main-content">
<div class="grid-container" id="polaroid-grid"></div>
<div id="loading">Loading more images...</div>
</div>
<script>
const gridContainer = document.getElementById('polaroid-grid');
const loadingIndicator = document.getElementById('loading');
const baseSize = 110; // Size of one grid cell in pixels
let page = 1;
let isLoading = false;
let hasMore = true;
function createPolaroid(polaroid) {
const polaroidElement = document.createElement('div');
polaroidElement.className = 'polaroid';
if (polaroid.height > polaroid.width) {
polaroidElement.classList.add('vertical');
}
polaroidElement.style.backgroundColor = `${polaroid.highlightColor}33`;
const img = document.createElement('img');
img.src = polaroid.imgSrc;
img.alt = polaroid.caption;
img.setAttribute('data-original-width', polaroid.width);
img.setAttribute('data-original-height', polaroid.height);
const dateOverlay = document.createElement('div');
dateOverlay.className = 'date-overlay';
dateOverlay.textContent = polaroid.date;
const caption = document.createElement('div');
caption.className = 'caption noto-sans-mono-font';
caption.textContent = polaroid.technicalInfo;
polaroidElement.appendChild(img);
polaroidElement.appendChild(dateOverlay);
polaroidElement.appendChild(caption);
return polaroidElement;
}
function calculateGridSpan(dimension) {
return Math.ceil(dimension / baseSize);
}
function positionPolaroid(polaroidElement, polaroid) {
const width = calculateGridSpan(polaroid.width + 20); // Add 20px for padding
const height = calculateGridSpan(polaroid.height + 40) + 1; // Add 40px for padding and caption
polaroidElement.style.gridColumnEnd = `span ${width}`;
polaroidElement.style.gridRowEnd = `span ${height}`;
}
function handleResize() {
const polaroids = document.querySelectorAll('.polaroid');
polaroids.forEach(polaroid => {
const img = polaroid.querySelector('img');
const width = parseInt(img.getAttribute('data-original-width'));
const height = parseInt(img.getAttribute('data-original-height'));
positionPolaroid(polaroid, { width, height });
});
}
async function loadImages() {
if (isLoading || !hasMore) return;
isLoading = true;
loadingIndicator.style.display = 'block';
try {
const response = await fetch(`/api/images?page=${page}`);
const data = await response.json();
data.images.forEach(polaroid => {
const polaroidElement = createPolaroid(polaroid);
positionPolaroid(polaroidElement, polaroid);
gridContainer.appendChild(polaroidElement);
});
hasMore = data.hasMore;
page++;
} catch (error) {
console.error('Error loading images:', error);
} finally {
isLoading = false;
loadingIndicator.style.display = 'none';
}
}
function handleScroll() {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 500) {
loadImages();
}
}
window.addEventListener('scroll', handleScroll);
loadImages(); // Initial load
</script>
</body>
</html>