+
@@ -291,14 +301,14 @@
thumb.classList.toggle('active', index === currentIndex);
});
- // Scroll active thumbnail into view
- // if (thumbnails[currentIndex]) {
- // thumbnails[currentIndex].scrollIntoView({
- // behavior: 'smooth',
- // block: 'nearest',
- // inline: 'center'
- // });
- // }
+ // Scroll active thumbnail into view
+ if (thumbnails[currentIndex]) {
+ thumbnails[currentIndex].scrollIntoView({
+ behavior: 'smooth',
+ block: 'nearest',
+ inline: 'center'
+ });
+ }
}
function goToFirst() {
@@ -350,6 +360,117 @@
function updateTimeline() {
const progress = images.length > 0 ? ((currentIndex + 1) / images.length) * 100 : 0;
document.getElementById('timelineProgress').style.width = progress + '%';
+ updateTimelineLabels();
+ }
+
+ function updateTimelineLabels() {
+ const labelsContainer = document.getElementById('timelineLabels');
+ labelsContainer.innerHTML = '';
+ if (images.length === 0) return;
+
+ const firstDate = images[0].createdDate;
+ const lastDate = images[images.length - 1].createdDate;
+ const totalDuration = lastDate.getTime() - firstDate.getTime();
+
+ // Aim for approximately 6-8 labels depending on the container width
+ const desiredLabels = Math.min(8, Math.max(6, Math.floor(window.innerWidth / 200)));
+
+ const labels = [];
+
+ // Always add the first timestamp
+ labels.push({
+ time: firstDate,
+ pos: 0
+ });
+
+ // Add evenly spaced timestamps
+ for (let i = 1; i < desiredLabels - 1; i++) {
+ const time = new Date(firstDate.getTime() + (totalDuration * i / (desiredLabels - 1)));
+
+ // Find closest image to this time
+ let closestIdx = 0;
+ let minDiff = Math.abs(images[0].createdDate - time);
+
+ for (let j = 1; j < images.length; j++) {
+ const diff = Math.abs(images[j].createdDate - time);
+ if (diff < minDiff) {
+ minDiff = diff;
+ closestIdx = j;
+ }
+ }
+
+ const pos = (closestIdx / (images.length - 1)) * 100;
+ labels.push({
+ time: images[closestIdx].createdDate,
+ pos: pos
+ });
+ }
+
+ // Add the last timestamp
+ labels.push({
+ time: lastDate,
+ pos: 100
+ });
+
+ // Remove any labels that are too close to each other
+ const filteredLabels = labels.filter((label, index) => {
+ if (index === 0) return true;
+ return Math.abs(label.pos - labels[index - 1].pos) >= 5;
+ });
+
+ // Calculate if we need to show seconds (if total duration is less than 5 minutes)
+ const showSeconds = totalDuration < 5 * 60 * 1000;
+
+ // Calculate optimal spacing between labels
+ const containerWidth = labelsContainer.offsetWidth;
+ const labelWidth = 70; // Approximate width of a time label
+ const minSpacing = labelWidth * 1.5; // Minimum space needed between labels
+ const maxLabels = Math.floor(containerWidth / minSpacing);
+ const targetLabels = Math.min(filteredLabels.length, maxLabels);
+
+ // Select evenly spaced labels
+ const finalLabels = [];
+ if (filteredLabels.length > 0) {
+ const step = (filteredLabels.length - 1) / (targetLabels - 1);
+ for (let i = 0; i < targetLabels; i++) {
+ const index = Math.round(i * step);
+ finalLabels.push(filteredLabels[index]);
+ }
+ }
+
+ // Round the timestamps
+ const roundedLabels = finalLabels.map(label => {
+ const newTime = new Date(label.time);
+
+ if (showSeconds) {
+ // Round seconds to nearest 5
+ const seconds = newTime.getSeconds();
+ const roundedSeconds = Math.round(seconds / 5) * 5;
+ newTime.setSeconds(roundedSeconds);
+ } else {
+ // Round minutes to nearest 5 and set seconds to 0
+ const minutes = newTime.getMinutes();
+ const roundedMinutes = Math.round(minutes / 5) * 5;
+ newTime.setMinutes(roundedMinutes);
+ newTime.setSeconds(0);
+ }
+
+ return {
+ ...label,
+ time: newTime
+ };
+ });
+
+ // Render labels
+ labelsContainer.style.position = 'relative';
+ labelsContainer.innerHTML = roundedLabels.map(l => {
+ const options = showSeconds
+ ? {hour: '2-digit', minute:'2-digit', second:'2-digit'}
+ : {hour: '2-digit', minute:'2-digit'};
+ return `
+ ${l.time.toLocaleTimeString([], options)}
+ `;
+ }).join('');
}
function togglePlay() {