Update index.html

This commit is contained in:
2024-08-07 23:20:13 +02:00
committed by GitHub
parent 8a1637db3a
commit c453ea331c
+277 -27
View File
@@ -416,6 +416,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
} }
.page-title { .page-title {
font-size: 3rem; /* Dies macht den Titel sehr groß */ font-size: 3rem; /* Dies macht den Titel sehr groß */
font-weight: bold; font-weight: bold;
@@ -456,31 +457,25 @@ header {
.button:hover { .button:hover {
background-color: #45a049; background-color: #45a049;
} }
#webcam-player { #webcam-player {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
max-height: 70vh; /* Begrenzt die Höhe auf 70% der Bildschirmhöhe */ max-height: 70vh; /* Begrenzt die Höhe auf 70% der Bildschirmhöhe */
display: block; display: block;
margin: 0 auto; margin: 702px auto 0; /* Fügt einen oberen Abstand von 20px hinzu */
} }
.video-container { .video-container {
position: relative; margin-top: 20px; /* Fügt einen oberen Abstand von 20px hinzu */
padding-bottom: 56.25%; /* 16:9 Seitenverhältnis */
height: 0;
overflow: hidden;
} }
.video-container #webcam-player { .video-container #webcam-player {
position: absolute;
top: 0;
left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.delete-btn { .delete-btn {
background-color: #ff4136; background-color: #ff4136;
color: white; color: white;
@@ -997,6 +992,12 @@ footer {
/* Rest des CSS bleibt unverändert */ /* Rest des CSS bleibt unverändert */
</style> </style>
@@ -1009,6 +1010,205 @@ footer {
</style> </style>
@@ -1058,7 +1258,7 @@ footer {
<section class="title-section"> <section class="title-section">
<div class="container"> <div class="container">
<div id="welcome-title">Willkommen bei Aurora Wetter Lifecam</div> <div id="welcome-title">Willkommen bei Aurora Wetter Lifecam</div>
<div id="welcome-subtitle">Erleben Sie faszinierende Ausblicke der Züricher Region - in Echtzeit!</div> <div id="welcome-subtitle">Erleben Sie faszinierende Ausblicke der Zürcher Region - in Echtzeit!</div>
</div> </div>
</section> </section>
@@ -1068,34 +1268,41 @@ footer {
<div class="sponsor-logos"> <div class="sponsor-logos">
<?php <?php
$advertisements = [ $advertisements = [
['name' => 'Gartencenter Meier', 'url' => 'https://www.gartencenter-meier.ch', 'img' => 'meier.png'], ['name' => 'Gartencenter Meier', 'url' => 'https://www.gartencenter-meier.ch', 'img' => 'meier.png', 'text' => 'Gartencenter Meier'],
['name' => 'Restaurant Schweizerhof', 'url' => 'https://schweizerhof-duernten.ch/', 'img' => 'schweiz.png'], ['name' => 'Restaurant Schweizerhof', 'url' => 'https://schweizerhof-duernten.ch/', 'img' => 'schweiz.png', 'text' => 'Hotel Schweizerhof'],
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png'], ['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png', 'text' => 'Werben Sie hier'],
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png'],
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png'], ['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png', 'text' => 'Werben Sie hier'],
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png'], ['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png', 'text' => 'Werben Sie hier'],
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png'], ['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png', 'text' => 'Werben Sie hier'],
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png']
// Fügen Sie hier weitere Werbeanzeigen hinzu
]; ];
$grouped_ads = array_chunk($advertisements, 5); $grouped_ads = array_chunk($advertisements, 3);
foreach ($grouped_ads as $group) { foreach ($grouped_ads as $group) {
echo '<div class="ad-row">'; echo '<div class="ad-row">';
foreach ($group as $ad) { foreach ($group as $ad) {
echo '<div class="ad-item"> echo '<div class="ad-item">
<a href="' . $ad['url'] . '" target="_blank"> <a href="' . htmlspecialchars($ad['url']) . '" target="_blank">
<img src="' . $ad['img'] . '" alt="' . $ad['name'] . '"> <img src="' . htmlspecialchars($ad['img']) . '" alt="' . htmlspecialchars($ad['name']) . '">
<p>' . htmlspecialchars($ad['text']) . '</p>
</a> </a>
</div>'; </div>';
} }
echo '</div>'; echo '</div>';
} }
?> ?>
</div> </div>
</div> </div>
</div> </div>
</div>
@@ -1106,9 +1313,17 @@ footer {
<div class="video-container"> <div class="video-container">
<?php echo $webcamManager->displayWebcam(); ?> <?php echo $webcamManager->displayWebcam(); ?>
<div id="timelapse-viewer" style="display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%;"> <div id="timelapse-viewer" class="video-container" style=" margin-top: 300px; max-width: 100%;
<img id="timelapse-image" src="" alt="Timelapse Image" style="width: 100%; height: 100%; object-fit: cover;"> height: auto;
max-height: 70vh;">
<img id="timelapse-image" src="" alt="Timelapse Image" class="video-container" style=" margin-top: 500px; max-width: 100%;
height: auto;
max-height: 70vh;">>
</div> </div>
</div> </div>
<div class="webcam-controls"> <div class="webcam-controls">
<a href="?action=snapshot" class="button">Snapshot speichern</a> <a href="?action=snapshot" class="button">Snapshot speichern</a>
@@ -1409,6 +1624,8 @@ document.addEventListener('DOMContentLoaded', function() {
sunnyTimelapseButton.textContent = 'Nur sonnige Bilder zeigen'; sunnyTimelapseButton.textContent = 'Nur sonnige Bilder zeigen';
} }
} }
const imageCache = new Map();
const preloadBuffer = 5; // Anzahl der im Voraus zu ladenden Bilder
async function startTimelapse() { async function startTimelapse() {
if (imageFiles.length === 0) { if (imageFiles.length === 0) {
@@ -1418,10 +1635,26 @@ document.addEventListener('DOMContentLoaded', function() {
timelapseInterval = setInterval(async function() { timelapseInterval = setInterval(async function() {
while (currentImageIndex < imageFiles.length) { while (currentImageIndex < imageFiles.length) {
const imageData = await getImageData(imageFiles[currentImageIndex]); const currentImage = imageFiles[currentImageIndex];
// Lazy Loading: Lade das aktuelle Bild und die nächsten paar
for (let i = currentImageIndex; i < currentImageIndex + preloadBuffer && i < imageFiles.length; i++) {
if (!imageCache.has(imageFiles[i])) {
imageCache.set(imageFiles[i], getImageData(imageFiles[i]));
}
}
const imageData = await imageCache.get(currentImage);
if (!isGreyImage(imageData) && (!showOnlySunny || isSunnyImage(imageData))) { if (!isGreyImage(imageData) && (!showOnlySunny || isSunnyImage(imageData))) {
timelapseImage.src = imageFiles[currentImageIndex]; timelapseImage.src = currentImage;
currentImageIndex++; currentImageIndex++;
// Cache-Bereinigung: Entferne alte Bilder aus dem Cache
if (imageCache.size > preloadBuffer * 2) {
const keysToDelete = Array.from(imageCache.keys()).slice(0, imageCache.size - preloadBuffer);
keysToDelete.forEach(key => imageCache.delete(key));
}
return; return;
} }
currentImageIndex++; currentImageIndex++;
@@ -1429,9 +1662,22 @@ document.addEventListener('DOMContentLoaded', function() {
currentImageIndex = 0; // Zurück zum Anfang, wenn alle Bilder durchlaufen wurden currentImageIndex = 0; // Zurück zum Anfang, wenn alle Bilder durchlaufen wurden
}, 500); }, 500);
} }
function updateTimelapseImage() {
timelapseImage.src = imageFiles[currentImageIndex];
timelapseSlider.value = currentImageIndex;
updateTimeDisplay();
}
function updateTimeDisplay() {
var date = new Date(imageFiles[currentImageIndex].match(/(\d{8}_\d{6})/)[1].replace(/_/g, 'T'));
timelapseTime.textContent = date.toLocaleString();
}
// Modifizierte getImageData-Funktion für Caching
function getImageData(src) { function getImageData(src) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (imageCache.has(src)) {
resolve(imageCache.get(src));
} else {
const img = new Image(); const img = new Image();
img.crossOrigin = "Anonymous"; img.crossOrigin = "Anonymous";
img.onload = function() { img.onload = function() {
@@ -1440,14 +1686,18 @@ function getImageData(src) {
canvas.height = this.height; canvas.height = this.height;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
ctx.drawImage(this, 0, 0); ctx.drawImage(this, 0, 0);
resolve(ctx.getImageData(0, 0, this.width, this.height)); const imageData = ctx.getImageData(0, 0, this.width, this.height);
imageCache.set(src, imageData);
resolve(imageData);
}; };
img.onerror = reject; img.onerror = reject;
img.src = src; img.src = src;
}
}); });
} }
function stopTimelapse() { function stopTimelapse() {
clearInterval(timelapseInterval); clearInterval(timelapseInterval);
currentImageIndex = 0; currentImageIndex = 0;